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

Spring Boot如何获取CSRF token 解决请求中CSRF token为null问题

问题:请求中获取到的CSRF Token为null

问题相关代码

  • 读取CSRF Token的实现代码
Object obj=request.getSession().getAttribute(WebSessionServerCsrfTokenRepository.class.getName().concat(".CSRF_TOKEN"));
  • 项目中CSRF Token生成配置代码
@Bean
public SecurityWebFilterChain securitygWebFilterChain(ServerHttpSecurity http) {
    http.csrf()
        .csrfTokenRepository(new WebSessionServerCsrfTokenRepository())
        .requireCsrfProtectionMatcher(getURLsForDisabledCSRF()).and()
        .authorizeExchange()
        .pathMatchers(ALLOWED_PATHS).permitAll()
        .pathMatchers(ALLOWED_METHODS).permitAll()
        .anyExchange()
        .authenticated().and()
        .securityContextRepository(NoOpServerSecurityContextRepository.getInstance()).formLogin().disable()
        .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint())
        .and().csrf(csrf -> csrf.csrfTokenRepository(CookieServerCsrfTokenRepository.withHttpOnlyFalse()));
    return http.build();
}
根因分析
  1. CSRF配置重复,后定义的规则覆盖了前面的规则
    同一段配置里先后定义了两套CSRF Token存储方案:第一套是基于WebSession存储的WebSessionServerCsrfTokenRepository,第二套是基于Cookie存储的CookieServerCsrfTokenRepository。Spring Security配置生效逻辑是同类型配置后定义的会覆盖先定义的,最终生效的是Cookie存储方案,根本不会往WebSession里写入CSRF_TOKEN属性,此时从Session读取必然返回null。
  2. CSRF Token默认懒加载,未触发生成逻辑时读取不到值
    Spring Security的CSRF Token默认不会在请求进入时就生成,只有当请求命中CSRF校验逻辑、或者代码主动触发Token生成时,才会把Token写入对应的存储介质,在这之前读取存储介质拿到的就是null。
  3. 无状态SecurityContext配置和Session存储Token逻辑冲突
    配置了NoOpServerSecurityContextRepository.getInstance()代表SecurityContext完全不存储在Session中,整套鉴权逻辑走无状态模式,这种场景下WebSession的属性持久化本身就可能受影响,进一步导致Session存Token失败。
解决步骤
  • 统一CSRF存储配置,删除重复定义
    二选一保留一种存储方案即可:如果要走Session存储Token,直接删除最后一行配置CookieServerCsrfTokenRepository的代码;如果要走Cookie存储Token,就删掉从Session读Token的逻辑,改为从请求Cookie中读取默认名为XSRF-TOKEN的字段值。
  • 主动触发Token生成,解决懒加载问题
    如果保留Session存储方案,新增一个全局WebFilter,在请求进入业务逻辑前主动触发Token生成和持久化,参考代码:
    @Bean
    public WebFilter csrfTokenPersistFilter(ServerCsrfTokenRepository csrfTokenRepository) {
        return (exchange, chain) -> {
            CsrfToken token = csrfTokenRepository.loadToken(exchange).block();
            if (token == null) {
                token = csrfTokenRepository.generateToken(exchange);
                csrfTokenRepository.saveToken(exchange, token).block();
            }
            exchange.getAttributes().put(CsrfToken.class.getName(), token);
            return chain.filter(exchange);
        };
    }
    
  • 校验Session可用性
    确认项目没有配置SessionCreationPolicy.STATELESS这类禁用Session的策略,WebFlux项目需要引入对应的Session依赖(比如spring-session-core、对应存储的spring-session组件),保证WebSession能正常持久化属性。
  • 校验CSRF白名单范围
    确认读取Token的接口不在getURLsForDisabledCSRF()定义的CSRF白名单路径内,白名单路径会跳过整套CSRF逻辑,不会生成对应Token。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 13:51:10