问题
I was trying to integrate oauth2 based token having client credential grant type with spring session based authentication. It's working fine with oauth token and the authorities given.
It's not working when I have combined them both. It always calls UsernamePasswordAuthenticationFilter and not OAuth2AuthenticationProcessingFilter
How to make them work together? Here is my ResourceServer configuration
@Configuration
@EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(SPARKLR_RESOURCE_ID).stateless(false);
}
@Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
// Since we want the protected resources to be accessible in the UI as well we need
// session creation to be allowed (it's disabled by default in 2.0.6)
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.and()
.requestMatchers().antMatchers("/api/account/**", "/oauth/users/**", "/oauth/clients/**","/me")
.and()
.authorizeRequests()
.antMatchers("/api/account/**").access("#oauth2.hasScope('read') or (!#oauth2.isOAuth() and hasRole('ROLE_USER'))")
.regexMatchers(HttpMethod.DELETE, "/oauth/users/([^/].*?)/tokens/.*")
.access("#oauth2.clientHasRole('ROLE_CLIENT') and (hasRole('ROLE_USER') or #oauth2.isClient()) and #oauth2.hasScope('write')")
.regexMatchers(HttpMethod.GET, "/oauth/clients/([^/].*?)/users/.*")
.access("#oauth2.clientHasRole('ROLE_CLIENT') and (hasRole('ROLE_USER') or #oauth2.isClient()) and #oauth2.hasScope('read')")
.regexMatchers(HttpMethod.GET, "/oauth/clients/.*")
.access("#oauth2.clientHasRole('ROLE_CLIENT') and #oauth2.isClient() and #oauth2.hasScope('read')");
// @formatter:on
}
}
The issue is, in filter chain OAuth2AuthenticationProcessingFilter is not getting called. So the token validation is not happening for any rest call. Below is the filter chain.
XNIO-2 task-1] o.s.security.web.FilterChainProxy : /api/account at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
XNIO-2 task-1] o.s.security.web.FilterChainProxy : /api/account at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
XNIO-2 task-1] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
XNIO-2 task-1] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: null. A new one will be created.
XNIO-2 task-1] o.s.security.web.FilterChainProxy : /api/account at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
XNIO-2 task-1] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@74d294b6
XNIO-2 task-1] o.s.security.web.FilterChainProxy : /api/account at position 4 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
XNIO-2 task-1] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/api/logout', GET]
XNIO-2 task-1] o.s.s.web.util.matcher.OrRequestMatcher : No matches found
XNIO-2 task-1] o.s.security.web.FilterChainProxy : /api/account at position 5 of 12 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
XNIO-2 task-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /api/account' doesn't match 'POST /api/authentication
XNIO-2 task-1] o.s.security.web.FilterChainProxy : /api/account at position 6 of 12 in additional filter chain; firing Filter: 'DefaultLoginPageGeneratingFilter'
XNIO-2 task-1] o.s.security.web.FilterChainProxy : /api/account at position 7 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
XNIO-2 task-1] o.s.security.web.FilterChainProxy : /api/account at position 8 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
XNIO-2 task-1] o.s.security.web.FilterChainProxy : /api/account at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
XNIO-2 task-1] o.s.s.w.a.AnonymousAuthenticationFilter : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials
XNIO-2 task-1] o.s.security.web.FilterChainProxy : /api/account at position 10 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter'
XNIO-2 task-1] o.s.security.web.FilterChainProxy : /api/account at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
XNIO-2 task-1] o.s.security.web.FilterChainProxy : /api/account at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
Edit: I'm trying to merge these 2 projects together. https://github.com/jhipster/jhipster-sample-app and https://github.com/spring-projects/spring-security-oauth/tree/master/samples/oauth2/sparklr
回答1:
You are using spring boot 1.5 so your resource server filter chain by default has a higher order than the custom filter chain that jhipster added. Either you need to change the orders, or change the pattern matchers so that the OAuth resources are not matched by the main filter chain. The spring boot user guide recommends that you put a custom filter chain in at a specific order (SecurityProperties.ACCESS_OVERRIDE_ORDER
). Probably a good a idea to follow that advice.
来源:https://stackoverflow.com/questions/42617218/how-oauth-token-based-and-session-based-authorization-works-together-in-spring