You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 2.7.8升级后Logout Handler阻塞,无法跳转至logoutSuccessUrl

Spring Boot 2.7.8(Spring Security 5.7.6)登出后无法重定向到指定地址

问题背景

将应用从Spring Boot 2.6.5升级至2.7.8(对应Spring Security 5.7.6),为后续升级到3.0版本做准备。升级前登出功能正常,但升级后登出流程完成后,始终无法重定向到logoutSuccessUrl()配置的地址。

过滤器链配置代码

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));

调试日志

[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

补充信息

  • 浏览器始终未跳转到/login?logoutSuccess=true,调试日志在上述最后一行终止
  • CSRF已启用,登出请求通过POST方式提交
  • 曾在logout配置中添加.permitAll(),无明显效果

解决方案尝试

1. 显式指定LogoutSuccessHandler

替代logoutSuccessUrl,直接自定义重定向逻辑,避免默认处理器的潜在问题:

.logout(logout -> logout
    .logoutUrl("/logout")
    .logoutSuccessHandler(new SimpleUrlLogoutSuccessHandler() {
        @Override
        public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
            response.sendRedirect("/login?logoutSuccess=true");
        }
    })
    .invalidateHttpSession(true)
    .deleteCookies(COOKIE_STRING)
)

2. 确保登出地址被允许访问

在authorizeHttpRequests中显式添加/logout到允许列表:

.authorizeHttpRequests((authz) -> authz
    .antMatchers("/webjars/**","/login/**","/logout","/mobile-manifest.json","/service-worker.js","/cache.manifest","/favicon.ico","/async/**","/api/**").permitAll()
    .anyRequest().authenticated()
)

3. 排查自定义过滤器拦截

检查应用中是否存在自定义Filter或拦截器,在LogoutFilter之后执行并修改了响应。可暂时禁用自定义过滤器,测试登出重定向是否恢复正常。

4. 临时禁用Remember-Me配置

日志显示remember-me服务在处理登出,可能其清理逻辑影响了响应流程。暂时注释remember-me配置,测试登出功能是否正常,再逐步排查。

5. 检查前端请求类型

如果登出请求是通过AJAX发起的,浏览器不会自动处理重定向响应。需要在前端代码中监听响应,手动执行页面跳转。

内容的提问来源于stack exchange,提问作者jn4

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 17:05:31