SpringBoot 3中禁用登出重定向并调用自定义登出REST端点
解决SpringBoot 3中Spring Security登出重定向问题,保留自定义/logout端点
要彻底禁用Spring Security的默认登出处理,避免自定义/logout端点被302重定向,可通过以下两种方式配置SecurityFilterChain:
方法一:修改默认登出匹配路径
将Spring Security的默认登出匹配路径设置为一个不存在的地址,让其永远不会触发:
@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http // 配置默认登出匹配不存在的路径,禁用默认逻辑 .logout(logout -> logout .logoutRequestMatcher(new AntPathRequestMatcher("/nonexistent-logout")) .permitAll() ) // 保留Keycloak OIDC JWT支持 .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults())) // 无状态会话,适配令牌认证 .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) // 放行所有请求(根据业务调整权限规则) .authorizeHttpRequests(auth -> auth.anyRequest().permitAll()) // 禁用默认登录页及HTTP Basic认证 .formLogin(form -> form.disable()) .httpBasic(basic -> basic.disable()); return http.build(); } }
方法二:直接绕过默认LogoutFilter
通过添加前置过滤器跳过Spring Security的LogoutFilter,彻底禁用默认登出处理:
@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http // 添加前置过滤器,直接放行,跳过默认LogoutFilter .addFilterBefore(new OncePerRequestFilter() { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { filterChain.doFilter(request, response); } }, LogoutFilter.class) // 保留Keycloak OIDC JWT支持 .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults())) // 无状态会话配置 .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) // 权限规则配置 .authorizeHttpRequests(auth -> auth.anyRequest().permitAll()) // 禁用默认登录相关组件 .formLogin(form -> form.disable()) .httpBasic(basic -> basic.disable()); return http.build(); } }
自定义登出端点示例
确保你的自定义/logout端点逻辑正常实现,比如清除Cookie令牌、调用Keycloak登出接口等:
@RestController public class CustomLogoutController { @PostMapping("/logout") public ResponseEntity<Void> handleLogout(HttpServletRequest request, HttpServletResponse response) { // 清除存储令牌的Cookie Cookie tokenCookie = new Cookie("auth-token", null); tokenCookie.setPath("/"); tokenCookie.setMaxAge(0); response.addCookie(tokenCookie); // 可选:调用Keycloak的登出端点(需根据Keycloak配置调整) // String logoutUrl = "http://your-keycloak-server/auth/realms/your-realm/protocol/openid-connect/logout"; // RestTemplate restTemplate = new RestTemplate(); // restTemplate.postForObject(logoutUrl, null, Void.class); return ResponseEntity.ok().build(); } }
以上配置后,Spring Security不会拦截/logout请求,直接交由自定义控制器处理,不会触发302重定向,同时保留原有Cookie认证和Keycloak OIDC的支持。
内容的提问来源于stack exchange,提问作者manjosh
相关产品推荐
相关产品推荐

