Home > Mobile >  Logout handler is hanging
Logout handler is hanging

Time:01-31

I'm upgrading a working application from Spring Boot 2.6.5 to 2.7.8 (Spring Security 5.7.6) so that I can better upgrade to 3.0.

Logout was working fine before. But after upgrading to Sprint Boot 2.7.8 the logout handling is hanging and never redirecting to the logoutSuccessUrl().

Here is the complete filter chain configuration:

      http
         .authorizeHttpRequests((authz) -> authz
            .antMatchers("/webjars/**","/login/**","/mobile-manifest.json","/service-worker.js","/cache.manifest","/favicon.ico","/async/**","/api/**").permitAll()
            .anyRequest().authenticated()
         )
         .httpBasic(withDefaults())
         .formLogin(formLogin -> formLogin
            .loginPage("/login")
            .permitAll()
            .loginProcessingUrl("/login")
            .successHandler(savedRequestAwareAuthenticationSuccessHandler())
            .failureUrl("/login?loginFailed=true"))
         .logout( logout -> logout
            .logoutUrl("/logout")
            .logoutSuccessUrl("/login?logoutSuccess=true")
            .invalidateHttpSession(true)
            .deleteCookies(COOKIE_STRING))
         .rememberMe( rememberMe -> rememberMe
            .key(TOKEN_KEY)
            .rememberMeParameter(REMEMBER_ME_KEY)
            .tokenRepository(persistentTokenRepository())
         .userDetailsService(userSvc)
            .tokenValiditySeconds(validitySeconds));

The output:

[https-jsse-nio-7001-exec-10] [DEBUG] [o.s.security.web.FilterChainProxy] - Securing POST /logout
[https-jsse-nio-7001-exec-10] [DEBUG] [o.s.s.w.c.HttpSessionSecurityContextRepository] - Retrieved SecurityContextImpl [Authentication=UsernamePasswordAuthenticationToken [Principal=UserProfile [ blah blah, eventRoles=null, lastLoginDisplay=today, directoryUrl=null, groups=[]], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=127.0.0.1, SessionId=740230E1C02B57BEF504C23570FFA9EC], Granted Authorities=[]]]
[https-jsse-nio-7001-exec-10] [DEBUG] [o.s.s.w.c.SecurityContextPersistenceFilter] - Set SecurityContextHolder to SecurityContextImpl [Authentication=UsernamePasswordAuthenticationToken [Principal=UserProfile [blah blah eventRoles=null, lastLoginDisplay=today, directoryUrl=null, groups=[]], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=127.0.0.1, SessionId=740230E1C02B57BEF504C23570FFA9EC], Granted Authorities=[]]]
[https-jsse-nio-7001-exec-10] [DEBUG] [o.s.s.w.a.logout.LogoutFilter] - Logging out [UsernamePasswordAuthenticationToken [Principal=UserProfile [blah blah, eventRoles=null, lastLoginDisplay=today, directoryUrl=null, groups=[]], Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=127.0.0.1, SessionId=740230E1C02B57BEF504C23570FFA9EC], Granted Authorities=[]]]
[https-jsse-nio-7001-exec-10] [DEBUG] [o.s.s.w.a.r.PersistentTokenBasedRememberMeServices] - Logout of user username
[https-jsse-nio-7001-exec-10] [DEBUG] [o.s.s.w.a.r.PersistentTokenBasedRememberMeServices] - Cancelling cookie
[https-jsse-nio-7001-exec-10] [DEBUG] [o.s.jdbc.core.JdbcTemplate] - Executing prepared SQL update
[https-jsse-nio-7001-exec-10] [DEBUG] [o.s.jdbc.core.JdbcTemplate] - Executing prepared SQL statement [delete from persistent_logins where username = ?]
[https-jsse-nio-7001-exec-10] [DEBUG] [o.s.jdbc.datasource.DataSourceUtils] - Fetching JDBC Connection from DataSource
[https-jsse-nio-7001-exec-10] [DEBUG] [o.s.s.w.a.l.SecurityContextLogoutHandler] - Invalidated session F3BC69312EC05C175A0FCEC298B49D06
[https-jsse-nio-7001-exec-10] [DEBUG] [o.s.s.w.c.HttpSessionSecurityContextRepository] - Did not store empty SecurityContext
[https-jsse-nio-7001-exec-10] [DEBUG] [o.s.s.w.c.HttpSessionSecurityContextRepository] - Did not store empty SecurityContext
[https-jsse-nio-7001-exec-10] [DEBUG] [o.s.s.w.c.SecurityContextPersistenceFilter] - Cleared SecurityContextHolder to complete request

Browser is never redirected to the loginSuccessUrl(), all DEBUG logging ends above. CSRF is enabled and logout was submitted POST.

I had .permitAll() in the logout configuration, but it seemed to have no effect in this case.

Screenshot showing request / response

CodePudding user response:

Spring Security provides two implementations of LogoutSuccessHandler, see LogoutSuccessHandler:

LogoutSuccessHandler

The LogoutSuccessHandler is called after a successful logout by the LogoutFilter, to handle (for example) redirection or forwarding to the appropriate destination. Note that the interface is almost the same as the LogoutHandler but may raise an exception.

Spring Security provides the following implementations:

  • SimpleUrlLogoutSuccessHandler

  • HttpStatusReturningLogoutSuccessHandler

As mentioned earlier, you need not specify the SimpleUrlLogoutSuccessHandler directly. Instead, the fluent API provides a shortcut by setting the logoutSuccessUrl(). This sets up the SimpleUrlLogoutSuccessHandler under the covers. The provided URL is redirected to after a logout has occurred. The default is /login?logout.

The HttpStatusReturningLogoutSuccessHandler can be interesting in REST API type scenarios. Instead of redirecting to a URL upon the successful logout, this LogoutSuccessHandler lets you provide a plain HTTP status code to be returned. If not configured, a status code 200 is returned by default.

If you configure HTTP basic authentication, the HttpStatusReturningLogoutSuccessHandler is added, see Default Logout Handler with HTTP Basic and XMLHttpRequest should be 204:

The default behavior for logout when the header X-Requested-With: XMLHttpRequest and HTTP Basic is enabled should be a 201. This will improve AngularJS experience which sends an accept header which includes text/html

See also: SEC-3103: Logout Success Content Negotiation.

  • Related