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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 17:01:21