Spring Boot 3.0.4无法将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

