Spring安全oauth2和表单登录配置
我的项目包含两个不同的部分,一个JSF管理面板和一个RESTfull服务。 我正在尝试设置SpringSecurity,根据用户导航的URL使用不同的身份验证方法 要求如下:Spring安全oauth2和表单登录配置,spring,spring-security,oauth-2.0,spring-java-config,Spring,Spring Security,Oauth 2.0,Spring Java Config,我的项目包含两个不同的部分,一个JSF管理面板和一个RESTfull服务。 我正在尝试设置SpringSecurity,根据用户导航的URL使用不同的身份验证方法 要求如下: 导航到JSF页面的用户将获得一个登录屏幕,在该屏幕上,他们使用表单身份验证进行身份验证 导航到REST服务的用户对令牌授予使用OAuth2隐式身份验证和基本身份验证 单独的配置可以自己工作,问题是当我尝试将它们结合在一个配置中时,在这种情况下,REST提供者似乎会妨碍并验证每个请求,即使请求转到管理url(这在spri
- 导航到JSF页面的用户将获得一个登录屏幕,在该屏幕上,他们使用表单身份验证进行身份验证
- 导航到REST服务的用户对令牌授予使用OAuth2隐式身份验证和基本身份验证
- 用于表单登录(JSF)
- OAuth2安全配置(REST)
@EnableResourceServer @订单(2) 公共类RestSecurityConfig扩展了WebSecurity配置适配器{ @注入 私有用户存储库用户存储库; @注入 专用密码编码器; @豆子 ApplicationListener loggerBean(){ 返回新的AuthenticationLoggerListener(); } @豆子 AccessDeniedHandler AccessDeniedHandler(){ 返回新的AccessDeniedExceptionHandler(); } @豆子 AuthenticationEntryPoint entryPointBean(){ 返回新的UnauthorizedEntryPoint(); } /*凌驾 public void configure(WebSecurity web)引发异常{ 忽略 蚂蚁配对者( “/resources/**” ,“/templates/**” ,“/login” ,“/注销” ,“/ui/**” ,“/401.html” ,“/404.html” ,“/500.html” ); }*/ @凌驾 受保护的无效配置(HttpSecurity http)引发异常{ ContentNegotiationStrategy ContentNegotiationStrategy=http.getSharedObject(ContentNegotiationStrategy.class); if(contentNegotiationStrategy==null){ contentNegotiationStrategy=新的HeaderContentNegotiationStrategy(); } MediaTypeRequestMatcher preferredMatcher=新的MediaTypeRequestMatcher(contentNegotiationStrategy, MediaType.APPLICATION\u FORM\u URLENCODED, MediaType.APPLICATION_JSON, MediaType.MULTIPART\u FORM\u DATA); http.authorizeRequests() .antMatchers(“/ui/**”).permitAll() .及() .anonymous().disable() .会议管理() .sessionCreationPolicy(sessionCreationPolicy.STATELESS) .and().httpBasic() .及() .例外处理() .accessDeniedHandler(accessDeniedHandler())//处理通常拒绝的访问(例如从@PreAuthorization提交) .authenticationEntryPoint(entryPointBean())//处理未经授权调用的身份验证异常。 .defaultAuthenticationEntryPointFor(entryPointBean(),preferredMatcher) .及() .授权请求() .antMatchers(“/api/**”).fullyAuthenticated(); } @凌驾 @豆子 公共AuthenticationManager authenticationManagerBean()引发异常{ 返回super.authenticationManagerBean(); } @凌驾 受保护的无效配置(AuthenticationManagerBuilder auth)引发异常{ auth.userDetailsService(新的userDetailsService(){ @凌驾 public UserDetails loadUserByUsername(字符串s)引发UsernameNotFoundException{ User User=userRepository.findOneByUsername; if(null==用户){ //让日志侦听器来处理 抛出新UsernameNotFoundException(“未找到带有电子邮件“+s+”的用户”); } 返回(UserDetails)用户; } }).密码编码器(passwordEncoder); } @配置 @EnableAuthorizationServer 受保护的静态类OAuth2Config扩展了AuthorizationServerConfigurerAdapter{ @自动连线 私人AuthenticationManager AuthenticationManager; @豆子 公共JwtAccessTokenConverter accessTokenConverter(){ 返回新的JwtAccessTokenConverter(); } @凌驾 public void configure(AuthorizationServerSecurityConfigure oauthServer)引发异常{ oauthServer.tokenKeyAccess(“isAnonymous()| | hasAuthority('ROLE_TRUSTED_CLIENT'))”)。checkTokenAccess(“hasAuthority('ROLE_TRUSTED_CLIENT')”); } @凌驾 public void configure(AuthorizationServerEndpointsConfigurer端点)引发异常{ endpoints.authenticationManager(authenticationManager).accessTokenConverter(accessTokenConverter()); } @凌驾 公共无效配置(ClientDetailsServiceConfigurer客户端)引发异常{ clients.inMemory() .与客户(“xxx”) .ResourceId(xxx) .authorizedGrantTypes(“密码”、“授权码”、“刷新令牌”、“隐式”) .权限(“角色客户”、“角色受信任客户”) .scopes(“读取”、“写入”、“信任”、“更新”) .accessTokenValiditySeconds(xxx) .refreshTokenValiditySeconds(xxx) .秘密(“xxx”) } } }
最好,我尝试调整您的安全配置。不幸的是,我无法验证该配置
@Override
@Order(1)
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.antMatchers("/templates/**").permitAll()
.antMatchers("/401.html").permitAll()
.antMatchers("/404.html").permitAll()
.antMatchers("/500.html").permitAll()
.antMatchers("/api/**").permitAll()
.antMatchers("/ui/admin.xhtml").hasAnyAuthority("admin", "ADMIN")
.antMatchers("/thymeleaf").hasAnyAuthority("admin", "ADMIN")
//.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/ui/index.xhtml")
.failureUrl("/login?error=1")
.permitAll()
.and()
.logout()
.permitAll()
.and()
.rememberMe()
.and().exceptionHandling().accessDeniedPage("/error/403");
@EnableResourceServer
@Order(2)
public class RestSecurityConfig extends WebSecurityConfigurerAdapter {
@Inject
private UserRepository userRepository;
@Inject
private PasswordEncoder passwordEncoder;
@Bean
ApplicationListener<AbstractAuthorizationEvent> loggerBean() {
return new AuthenticationLoggerListener();
}
@Bean
AccessDeniedHandler accessDeniedHandler() {
return new AccessDeniedExceptionHandler();
}
@Bean
AuthenticationEntryPoint entryPointBean() {
return new UnauthorizedEntryPoint();
}
/*Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers(
"/resources/**"
, "/templates/**"
, "/login"
, "/logout"
, "/ui/**"
, "/401.html"
, "/404.html"
, "/500.html"
);
}*/
@Override
protected void configure(HttpSecurity http) throws Exception {
ContentNegotiationStrategy contentNegotiationStrategy = http.getSharedObject(ContentNegotiationStrategy.class);
if (contentNegotiationStrategy == null) {
contentNegotiationStrategy = new HeaderContentNegotiationStrategy();
}
MediaTypeRequestMatcher preferredMatcher = new MediaTypeRequestMatcher(contentNegotiationStrategy,
MediaType.APPLICATION_FORM_URLENCODED,
MediaType.APPLICATION_JSON,
MediaType.MULTIPART_FORM_DATA);
http.authorizeRequests()
.antMatchers("/ui/**").permitAll()
.and()
.anonymous().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().httpBasic()
.and()
.exceptionHandling()
.accessDeniedHandler(accessDeniedHandler()) // handle access denied in general (for example comming from @PreAuthorization
.authenticationEntryPoint(entryPointBean()) // handle authentication exceptions for unauthorized calls.
.defaultAuthenticationEntryPointFor(entryPointBean(), preferredMatcher)
.and()
.authorizeRequests()
.antMatchers("/api/**").fullyAuthenticated();
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(new UserDetailsService() {
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
User user = userRepository.findOneByUsername(s);
if (null == user) {
// leave that to be handled by log listener
throw new UsernameNotFoundException("The user with email " + s + " was not found");
}
return (UserDetails) user;
}
}).passwordEncoder(passwordEncoder);
}
@Configuration
@EnableAuthorizationServer
protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
return new JwtAccessTokenConverter();
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("isAnonymous() || hasAuthority('ROLE_TRUSTED_CLIENT')").checkTokenAccess("hasAuthority('ROLE_TRUSTED_CLIENT')");
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager).accessTokenConverter(accessTokenConverter());
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("xxx")
.resourceIds(xxx)
.authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
.authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
.scopes("read", "write", "trust", "update")
.accessTokenValiditySeconds(xxx)
.refreshTokenValiditySeconds(xxx)
.secret("xxx")
}
}
}
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserRepository userRepository;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(new UserDetailsService() {
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
User user = userRepository.findOneByUsername(s);
if (null == user) {
throw new UsernameNotFoundException("The user with email " + s + " was not found");
}
return (UserDetails) user;
}
}).passwordEncoder(passwordEncoder);
}
@Override
public void configure(WebSecurity webSecurity) throws Exception {
webSecurity
.ignoring()
.antMatchers("/resources/**"
, "/templates/**"
, "/login"
, "/logout"
, "/ui/**"
, "/401.html"
, "/404.html"
, "/500.html");
}
@Configuration
@EnableAuthorizationServer
public static class OAuth2Configuration extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Bean
public JwtAccessTokenConverter accessTokenConverter() {
return new JwtAccessTokenConverter();
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("isAnonymous() || hasAuthority('ROLE_TRUSTED_CLIENT')").checkTokenAccess("hasAuthority('ROLE_TRUSTED_CLIENT')");
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager).accessTokenConverter(accessTokenConverter());
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("xxx")
.resourceIds("xxx")
.authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
.authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
.scopes("read", "write", "trust", "update")
.accessTokenValiditySeconds(xxx)
.refreshTokenValiditySeconds(xxx)
.secret("xxx");
}
}
@Configuration
@Order(1)
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/ui/admin.xhtml").hasAnyAuthority("admin", "ADMIN")
.antMatchers("/thymeleaf").hasAnyAuthority("admin", "ADMIN")
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/ui/index.xhtml")
.failureUrl("/login?error=1")
.permitAll()
.and()
.logout()
.permitAll()
.and()
.rememberMe()
.and().exceptionHandling().accessDeniedPage("/error/403");
}
}
@Order(2)
@Configuration
@EnableResourceServer
public static class CustomResourceServerConfigurerAdapter extends ResourceServerConfigurerAdapter {
@Bean
ApplicationListener<AbstractAuthorizationEvent> loggerBean() {
return new AuthenticationLoggerListener();
}
@Bean
AccessDeniedHandler accessDeniedHandler() {
return new AccessDeniedExceptionHandler();
}
@Bean
AuthenticationEntryPoint entryPointBean() {
return new UnauthorizedEntryPoint();
}
@Override
public void configure(HttpSecurity http) throws Exception {
ContentNegotiationStrategy contentNegotiationStrategy = http.getSharedObject(ContentNegotiationStrategy.class);
if (contentNegotiationStrategy == null) {
contentNegotiationStrategy = new HeaderContentNegotiationStrategy();
}
MediaTypeRequestMatcher preferredMatcher = new MediaTypeRequestMatcher(contentNegotiationStrategy,
MediaType.APPLICATION_FORM_URLENCODED,
MediaType.APPLICATION_JSON,
MediaType.MULTIPART_FORM_DATA);
http.authorizeRequests()
.and()
.anonymous().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().httpBasic()
.and()
.exceptionHandling()
.accessDeniedHandler(accessDeniedHandler()) // handle access denied in general (for example comming from @PreAuthorization
.authenticationEntryPoint(entryPointBean()) // handle authentication exceptions for unauthorized calls.
.defaultAuthenticationEntryPointFor(entryPointBean(), preferredMatcher)
.and()
.authorizeRequests()
.antMatchers("/api/**").fullyAuthenticated();
}
}
}