Spring Security 6中CSRF保护失效问题求助
Spring Boot 3/Spring Security 6下CSRF保护失效的修复方案
问题根源
你猜测的没错,这个问题确实和Spring Security的令牌存储机制变更有关。在Spring Security 6中,CookieCsrfTokenRepository默认会对存储在Cookie中的令牌进行XOR加密处理,前端直接读取的是加密后的令牌,和后端期望的原始令牌不匹配,导致验证失败。
解决方案
有两种可行的修复方式:
方式1:禁用XOR加密(快速兼容旧逻辑)
如果想保持和Spring Boot 2.x完全一致的行为,可以自定义Cookie序列化器,禁用令牌加密:
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { return http .authorizeHttpRequests(authorize -> authorize .anyRequest().authenticated()) .httpBasic(withDefaults()) .sessionManagement(session -> session .sessionCreationPolicy(SessionCreationPolicy.ALWAYS)) .csrf(csrf -> csrf .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse() .setCookieSerializer(new CookieSerializer() { @Override public Cookie serializeCookie(CsrfToken token) { Cookie cookie = new Cookie(token.getCookieName(), token.getToken()); cookie.setPath("/"); cookie.setHttpOnly(false); cookie.setSameSite("Lax"); return cookie; } @Override public CsrfToken deserializeCookie(Cookie cookie) { return new DefaultCsrfToken( CookieCsrfTokenRepository.DEFAULT_CSRF_HEADER_NAME, CookieCsrfTokenRepository.DEFAULT_CSRF_PARAMETER_NAME, cookie.getValue() ); } }))) .build(); }
方式2:适配加密令牌(推荐,符合新规范)
Spring Security 6提供了CsrfTokenRequestAttributeHandler来处理加密令牌的验证逻辑,只需配置后端正确识别前端传递的加密令牌即可,前端代码无需修改:
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { CsrfTokenRequestAttributeHandler requestHandler = new CsrfTokenRequestAttributeHandler(); // 清空请求属性名,让处理器直接从请求头读取令牌 requestHandler.setCsrfRequestAttributeName(null); return http .authorizeHttpRequests(authorize -> authorize .anyRequest().authenticated()) .httpBasic(withDefaults()) .sessionManagement(session -> session .sessionCreationPolicy(SessionCreationPolicy.ALWAYS)) .csrf(csrf -> csrf .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) .csrfTokenRequestHandler(requestHandler)) .build(); }
验证要点
- 确保第二次点击按钮时,浏览器中已存在
XSRF-TOKENCookie; - 确认请求头
X-XSRF-Token的值与Cookie中的值完全一致; - 检查后端日志,
Invalid CSRF token的错误信息应不再出现。
内容的提问来源于stack exchange,提问作者Dimitri Mestdagh
相关产品推荐
相关产品推荐

