简体   繁体   English

注销处理程序挂起

[英]Logout handler is hanging

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.我正在将工作应用程序从 Spring Boot 2.6.5 升级到 2.7.8 (Spring Security 5.7.6),以便我可以更好地升级到 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() .但是在升级到 Sprint Boot 2.7.8 之后,注销处理挂起并且永远不会重定向到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: 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.浏览器永远不会重定向到loginSuccessUrl() ,所有 DEBUG 日志记录都在上面结束。 CSRF is enabled and logout was submitted POST .启用 CSRF 并且已提交注销POST

I had .permitAll() in the logout configuration, but it seemed to have no effect in this case.我在注销配置中有.permitAll() ,但在这种情况下似乎没有效果。

Screenshot showing request / response显示请求/响应的屏幕截图

Spring Security provides two implementations of LogoutSuccessHandler , see LogoutSuccessHandler : Spring Security 提供了LogoutSuccessHandler的两种实现,参见LogoutSuccessHandler

LogoutSuccessHandler注销成功处理程序

The LogoutSuccessHandler is called after a successful logout by the LogoutFilter , to handle (for example) redirection or forwarding to the appropriate destination. LogoutSuccessHandlerLogoutFilter成功注销后调用,以处理(例如)重定向或转发到适当的目的地。 Note that the interface is almost the same as the LogoutHandler but may raise an exception.请注意,该接口与LogoutHandler几乎相同,但可能会引发异常。

Spring Security provides the following implementations: Spring Security 提供了以下实现:

  • SimpleUrlLogoutSuccessHandler SimpleUrlLogoutSuccessHandler

  • HttpStatusReturningLogoutSuccessHandler HttpStatusReturningLogoutSuccessHandler

As mentioned earlier, you need not specify the SimpleUrlLogoutSuccessHandler directly.如前所述,您无需直接指定SimpleUrlLogoutSuccessHandler Instead, the fluent API provides a shortcut by setting the logoutSuccessUrl() .相反,流畅的 API 通过设置logoutSuccessUrl()提供了一个快捷方式。 This sets up the SimpleUrlLogoutSuccessHandler under the covers.这会在幕后设置SimpleUrlLogoutSuccessHandler The provided URL is redirected to after a logout has occurred.提供的 URL 在注销发生后被重定向到。 The default is /login?logout .默认为/login?logout

The HttpStatusReturningLogoutSuccessHandler can be interesting in REST API type scenarios. HttpStatusReturningLogoutSuccessHandler在 REST API 类型的场景中可能很有趣。 Instead of redirecting to a URL upon the successful logout, this LogoutSuccessHandler lets you provide a plain HTTP status code to be returned.LogoutSuccessHandler允许您提供要返回的纯 HTTP 状态代码,而不是在成功注销后重定向到 URL。 If not configured, a status code 200 is returned by default.如果未配置,则默认返回状态码 200。

If you configure HTTP basic authentication, the HttpStatusReturningLogoutSuccessHandler is added, see Default Logout Handler with HTTP Basic and XMLHttpRequest should be 204 :如果配置 HTTP 基本身份验证,则会添加HttpStatusReturningLogoutSuccessHandler ,请参阅 默认注销处理程序 HTTP Basic 和 XMLHttpRequest 应该是 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当启用 header X-Requested-With: XMLHttpRequest 和 HTTP Basic 时注销的默认行为应该是 201。这将改善 AngularJS 发送接受 header 的体验,其中包括文本/html

See also: SEC-3103: Logout Success Content Negotiation .另请参阅: SEC-3103:注销成功内容协商

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM