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

Spring Boot 3.0.4无法将XSRF-TOKEN写入响应Cookie的问题求助

解决Spring WebFlux中XSRF-TOKEN Cookie生成及校验问题

问题1:配置CookieServerCsrfTokenRepository后未生成Cookie

Spring WebFlux中CSRF Token是按需生成的:仅当请求触发CSRF校验(如POST/PUT/DELETE等非安全方法),或代码显式订阅CsrfToken时,才会生成并写入Cookie。你的根路径/是GET请求且配置了permitAll,默认不会触发Token生成。

解决方法

在Security配置中添加后置Filter,主动加载CsrfToken,确保所有请求(包括GET)都能生成Token并写入Cookie:

@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
    CookieServerCsrfTokenRepository csrfRepo = CookieServerCsrfTokenRepository.withHttpOnlyFalse();
    ServerCsrfTokenRequestAttributeHandler csrfRequestHandler = new ServerCsrfTokenRequestAttributeHandler();

    http
        .oauth2Login(oauth2 -> oauth2
            // 保留你的failure handler配置
        )
        .csrf(csrf -> csrf
            .csrfTokenRepository(csrfRepo)
            .csrfTokenRequestHandler(csrfRequestHandler)
        )
        .authorizeExchange(exchanges -> exchanges
            .pathMatchers("/").permitAll()
            .anyExchange().authenticated()
        )
        .headers(headers -> headers
            .frameOptions(frame -> frame.mode(XFrameOptionsServerHttpHeadersWriter.Mode.SAMEORIGIN))
        )
        .cors()
        .and()
        .logout(logout -> logout
            .logoutHandler(logoutHandler())
            .logoutSuccessHandler(oidcLogoutSuccessHandler(this.postLogoutRedirectUri))
        )
        .exceptionHandling(exceptions -> exceptions
            .authenticationEntryPoint(/* 你的配置 */)
        );

    // 主动加载CsrfToken,触发Cookie写入
    http.addFilterAfter((exchange, chain) -> 
        exchange.getAttributeOrDefault(CsrfToken.class.getName(), Mono.empty())
            .cast(CsrfToken.class)
            .then(chain.filter(exchange)), 
        SecurityWebFiltersOrder.CSRF
    );

    return http.build();
}

问题2:自定义过滤器生成的Token过长(4936字符)

你的自定义CsrfHelperFilter中,从exchange.getAttribute(CsrfToken.class.getName())获取的对象并非正确的CSRF Token实例——在未正确配置csrfTokenRepository的场景下,该属性可能被错误填充为OAuth2相关的长Token(如ID Token),导致Cookie超出浏览器4096字符限制。

解决方法

移除自定义的CsrfHelperFilter,依赖Spring Security原生的CookieServerCsrfTokenRepository生成Token:它默认生成短随机字符串(约32位),不会触发长度限制错误。

问题3:不配置csrf参数时POST请求返回403

Spring Security默认启用CSRF保护,此时会使用默认的CsrfTokenRepository生成Token。但你的自定义过滤器生成的Token与Security校验时使用的Token并非同一实例,导致校验失败。

解决方法

必须保证Token的生成与校验使用同一个CsrfTokenRepository——即通过Security配置统一管理,而非自定义过滤器单独生成。

关键注意事项

  • CookieServerCsrfTokenRepository.withHttpOnlyFalse()必须设置,否则前端无法读取Cookie中的Token。
  • 主动加载CsrfToken的Filter必须放在SecurityWebFiltersOrder.CSRF之后,确保Security已经完成Token的初始化。
  • 前端发送POST请求时,需将XSRF-TOKEN的值放入请求头X-XSRF-TOKEN中,Spring Security会自动校验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 10:02:47