Spring Security启用CSRF后登录请求强制返回HTTP 302的问题
Spring Security启用CSRF后登录请求返回302而非204的问题解决
问题背景
- 基于Spring Boot 3.3.0 + Spring Security 6.3.0的后端服务,为独立Angular前端提供登录接口
- 关闭CSRF防护时,登录请求正常返回HTTP 204;启用
CookieCsrfTokenRepository后,登录请求被强制返回302重定向,自定义的formLogin.successHandler完全失效 - 即使请求头携带
X-XSRF-TOKEN,服务器仍返回403提示CSRF token无效;若将/login加入CSRF忽略列表,登录可返回204,但响应中无CSRF token,后续POST请求依旧触发302重定向
部署环境
- 前端由Apache HTTPD托管,后端为Spring Boot应用,二者共享同一FQDN但对应不同路径
- 请求通过HAProxy转发,HAProxy会自动移除请求路径中的
/web-gui/backend前缀
解决方案
1. 修正CSRF Token的Cookie配置
同FQDN跨路径场景下,必须确保CSRF Token的Cookie属性适配前端访问路径,否则前端无法读取或携带正确的Token:
@Bean public CsrfTokenRepository csrfTokenRepository() { CookieCsrfTokenRepository repo = CookieCsrfTokenRepository.withHttpOnlyFalse(); // 设置Cookie路径为根目录,确保Angular前端能获取到 repo.setCookiePath("/"); // 指定Cookie的Domain为当前FQDN,避免跨路径访问限制 repo.setCookieDomain("your-domain.com"); // SameSite设为Lax(同FQDN场景下足够,若有跨域需求可设为None并开启HTTPS) repo.setCookieSameSite("Lax"); return repo; }
Angular会自动读取XSRF-TOKEN Cookie,并在POST/PUT/DELETE请求中自动携带X-XSRF-TOKEN请求头,无需额外前端代码,只要Cookie属性配置正确即可。
2. 禁用Spring Security默认的登录重定向
前后端分离场景下,必须覆盖Spring Security默认的登录成功重定向逻辑,使用自定义successHandler返回2xx响应:
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .csrf(csrf -> csrf.csrfTokenRepository(csrfTokenRepository())) .formLogin(form -> form .loginProcessingUrl("/login") // 自定义成功处理器,返回204不重定向 .successHandler((req, res, auth) -> { res.setStatus(HttpStatus.NO_CONTENT.value()); // 确保CSRF Token被写入响应(Spring Security通常会自动处理,此处为兜底) CsrfToken csrfToken = req.getAttribute(CsrfToken.class.getName()); if (csrfToken != null) { res.setHeader(csrfToken.getHeaderName(), csrfToken.getToken()); } }) // 自定义失败处理器,返回401而非重定向 .failureHandler((req, res, ex) -> res.setStatus(HttpStatus.UNAUTHORIZED.value())) ); return http.build(); }
注意:不要将/login加入CSRF忽略列表,否则Spring Security不会为登录请求生成CSRF Token,导致后续请求无有效Token可用。
3. 适配HAProxy的路径改写
由于HAProxy会移除/web-gui/backend前缀,需要让Spring Boot服务的上下文路径与HAProxy的前缀匹配,避免路径不匹配导致的Cookie或请求映射问题:
在application.properties中添加:
server.servlet.context-path=/web-gui/backend
这样Spring Boot会自动处理路径映射,HAProxy移除前缀后,后端能正确匹配请求,同时CSRF Token的Cookie路径也能与前端访问路径兼容。
关于302重定向的适配
只要完成上述配置,无需修改前端适配302重定向。Spring Security默认的302重定向是为传统服务器端渲染场景设计的,前后端分离场景下必须通过自定义successHandler返回2xx响应,保持接口的RESTful风格。
内容的提问来源于stack exchange,提问作者Gábor Major
相关产品推荐
相关产品推荐

