I have set up an Spring Boot application with Oauth2 authentication using this tutorial.
The Problem is that the logout is not working, users can still access restricted resources after calling logout.
Log output:
2016-09-06 14:27:14.220 DEBUG 2272 --- [o-28080-exec-10] o.s.security.web.FilterChainProxy : /logout at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2016-09-06 14:27:14.220 DEBUG 2272 --- [o-28080-exec-10] o.s.security.web.FilterChainProxy : /logout at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2016-09-06 14:27:14.220 DEBUG 2272 --- [o-28080-exec-10] o.s.security.web.FilterChainProxy : /logout at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2016-09-06 14:27:14.220 DEBUG 2272 --- [o-28080-exec-10] o.s.security.web.FilterChainProxy : /logout at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2016-09-06 14:27:14.220 DEBUG 2272 --- [o-28080-exec-10] o.s.security.web.FilterChainProxy : /logout at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2016-09-06 14:27:14.220 DEBUG 2272 --- [o-28080-exec-10] w.c.HttpSessionSecurityContextRepository : Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT: 'org.springframework.security.core.context.SecurityContextImpl@269ad8d6: Authentication: org.springframework.security.oauth2.provider.OAuth2Authentication@269ad8d6: Principal: unknown; Credentials: [PROTECTED]; Authenticated: true; Details: remoteAddress=0:0:0:0:0:0:0:1, sessionId=<SESSION>, tokenType=bearertokenValue=<TOKEN>; Granted Authorities: ROLE_USER'
2016-09-06 14:27:14.220 DEBUG 2272 --- [o-28080-exec-10] o.s.security.web.FilterChainProxy : /logout at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2016-09-06 14:27:14.220 DEBUG 2272 --- [o-28080-exec-10] o.s.security.web.FilterChainProxy : /logout at position 4 of 12 in additional filter chain; firing Filter: 'CsrfFilter'
2016-09-06 14:27:14.220 DEBUG 2272 --- [o-28080-exec-10] o.s.security.web.FilterChainProxy : /logout at position 5 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
2016-09-06 14:27:14.220 DEBUG 2272 --- [o-28080-exec-10] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/logout'; against '/logout'
2016-09-06 14:27:48.801 DEBUG 2272 --- [o-28080-exec-10] o.s.s.w.a.logout.LogoutFilter : Logging out user 'org.springframework.security.oauth2.provider.OAuth2Authentication@269ad8d6: Principal: unknown; Credentials: [PROTECTED]; Authenticated: true; Details: remoteAddress=0:0:0:0:0:0:0:1, sessionId=<SESSION>, tokenType=bearertokenValue=<TOKEN>; Granted Authorities: ROLE_USER' and transferring to logout destination
2016-09-06 14:28:06.314 DEBUG 2272 --- [o-28080-exec-10] o.s.s.w.a.l.SecurityContextLogoutHandler : Invalidating session: B5A170AE88346E034E446939A7F319A4
2016-09-06 14:28:09.198 DEBUG 2272 --- [o-28080-exec-10] .s.s.w.a.l.SimpleUrlLogoutSuccessHandler : Using default Url: /
2016-09-06 14:28:09.201 DEBUG 2272 --- [o-28080-exec-10] o.s.s.web.DefaultRedirectStrategy : Redirecting to '/'
2016-09-06 14:28:09.203 DEBUG 2272 --- [o-28080-exec-10] 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@764f1e9f
2016-09-06 14:28:09.205 DEBUG 2272 --- [o-28080-exec-10] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2016-09-06 14:29:52.667 DEBUG 2272 --- [o-28080-exec-10] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2016-09-06 14:29:52.709 DEBUG 2272 --- [io-28080-exec-8] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/css/**']
2016-09-06 14:29:52.709 DEBUG 2272 --- [io-28080-exec-8] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/'; against '/css/**'
2016-09-06 14:29:52.709 DEBUG 2272 --- [io-28080-exec-8] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/js/**']
2016-09-06 14:29:52.709 DEBUG 2272 --- [io-28080-exec-8] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/'; against '/js/**'
2016-09-06 14:29:52.709 DEBUG 2272 --- [io-28080-exec-8] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/images/**']
2016-09-06 14:29:52.709 DEBUG 2272 --- [io-28080-exec-8] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/'; against '/images/**'
2016-09-06 14:29:52.709 DEBUG 2272 --- [io-28080-exec-8] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/webjars/**']
2016-09-06 14:29:52.709 DEBUG 2272 --- [io-28080-exec-8] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/'; against '/webjars/**'
2016-09-06 14:29:52.709 DEBUG 2272 --- [io-28080-exec-8] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/**/favicon.ico']
2016-09-06 14:29:52.709 DEBUG 2272 --- [io-28080-exec-8] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/'; against '/**/favicon.ico'
2016-09-06 14:29:52.710 DEBUG 2272 --- [io-28080-exec-8] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/error']
2016-09-06 14:29:52.710 DEBUG 2272 --- [io-28080-exec-8] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/'; against '/error'
2016-09-06 14:29:52.710 DEBUG 2272 --- [io-28080-exec-8] o.s.s.web.util.matcher.OrRequestMatcher : No matches found
2016-09-06 14:29:52.710 DEBUG 2272 --- [io-28080-exec-8] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/'; against '/assets/**'
2016-09-06 14:29:52.710 DEBUG 2272 --- [io-28080-exec-8] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/'; against '/webjars/**'
2016-09-06 14:29:52.710 DEBUG 2272 --- [io-28080-exec-8] o.s.security.web.FilterChainProxy : / at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2016-09-06 14:29:52.710 DEBUG 2272 --- [io-28080-exec-8] o.s.security.web.FilterChainProxy : / at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2016-09-06 14:29:52.710 DEBUG 2272 --- [io-28080-exec-8] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
2016-09-06 14:29:52.711 DEBUG 2272 --- [io-28080-exec-8] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: null. A new one will be created.
2016-09-06 14:29:52.712 DEBUG 2272 --- [io-28080-exec-8] o.s.security.web.FilterChainProxy : / at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2016-09-06 14:29:52.712 DEBUG 2272 --- [io-28080-exec-8] o.s.security.web.FilterChainProxy : / at position 4 of 12 in additional filter chain; firing Filter: 'CsrfFilter'
2016-09-06 14:29:52.712 DEBUG 2272 --- [io-28080-exec-8] o.s.security.web.FilterChainProxy : / at position 5 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
2016-09-06 14:29:52.713 DEBUG 2272 --- [io-28080-exec-8] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /' doesn't match 'POST /logout
2016-09-06 14:29:52.713 DEBUG 2272 --- [io-28080-exec-8] o.s.security.web.FilterChainProxy : / at position 6 of 12 in additional filter chain; firing Filter: 'OAuth2ClientAuthenticationProcessingFilter'
2016-09-06 14:29:52.713 DEBUG 2272 --- [io-28080-exec-8] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/'; against '/login'
2016-09-06 14:29:52.713 DEBUG 2272 --- [io-28080-exec-8] o.s.security.web.FilterChainProxy : / at position 7 of 12 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2016-09-06 14:29:52.713 DEBUG 2272 --- [io-28080-exec-8] o.s.security.web.FilterChainProxy : / at position 8 of 12 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2016-09-06 14:29:52.713 DEBUG 2272 --- [io-28080-exec-8] o.s.security.web.FilterChainProxy : / at position 9 of 12 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2016-09-06 14:29:52.713 DEBUG 2272 --- [io-28080-exec-8] o.s.s.w.a.AnonymousAuthenticationFilter : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS'
2016-09-06 14:29:52.713 DEBUG 2272 --- [io-28080-exec-8] o.s.security.web.FilterChainProxy : / at position 10 of 12 in additional filter chain; firing Filter: 'SessionManagementFilter'
2016-09-06 14:29:52.713 DEBUG 2272 --- [io-28080-exec-8] o.s.s.w.session.SessionManagementFilter : Requested session ID B5A170AE88346E034E446939A7F319A4 is invalid.
2016-09-06 14:29:52.714 DEBUG 2272 --- [io-28080-exec-8] o.s.security.web.FilterChainProxy : / at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2016-09-06 14:29:52.714 DEBUG 2272 --- [io-28080-exec-8] o.s.security.web.FilterChainProxy : / at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2016-09-06 14:29:52.714 DEBUG 2272 --- [io-28080-exec-8] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /' doesn't match 'POST /logout
2016-09-06 14:29:52.714 DEBUG 2272 --- [io-28080-exec-8] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /; Attributes: [permitAll]
2016-09-06 14:29:52.714 DEBUG 2272 --- [io-28080-exec-8] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
2016-09-06 14:29:52.715 DEBUG 2272 --- [io-28080-exec-8] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@5f0b1dd7, returned: 1
2016-09-06 14:29:52.715 DEBUG 2272 --- [io-28080-exec-8] o.s.s.w.a.i.FilterSecurityInterceptor : Authorization successful
2016-09-06 14:29:52.716 DEBUG 2272 --- [io-28080-exec-8] o.s.s.w.a.i.FilterSecurityInterceptor : RunAsManager did not change Authentication object
2016-09-06 14:29:52.716 DEBUG 2272 --- [io-28080-exec-8] o.s.security.web.FilterChainProxy : / reached end of additional filter chain; proceeding with original chain
2016-09-06 14:29:52.772 DEBUG 2272 --- [io-28080-exec-8] 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@764f1e9f
2016-09-06 14:29:52.772 DEBUG 2272 --- [io-28080-exec-8] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2016-09-06 14:29:53.322 DEBUG 2272 --- [io-28080-exec-8] o.s.s.w.a.ExceptionTranslationFilter : Chain processed normally
2016-09-06 14:29:53.322 DEBUG 2272 --- [io-28080-exec-8] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
Config:
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
@EnableOAuth2Sso
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
{
@Override
public void configure(WebSecurity web) throws Exception
{
web.ignoring().antMatchers("/assets/**", "/webjars/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception
{
http.authorizeRequests().antMatchers("blacklist...**").hasRole("USER")
.and().authorizeRequests().antMatchers("/**").permitAll()
.and().anonymous()
.and().logout().logoutSuccessUrl("/").permitAll()
.and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and().headers().frameOptions().disable().contentTypeOptions().and().xssProtection()
.xssProtectionEnabled(true).and().cacheControl();
}
}