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

开启Spring Security CSRF防护后所有非GET请求被禁止的问题

问题分析与解决方案

你的问题核心在于无状态JWT会话模式与Spring Security默认CSRF机制不兼容:

  • Spring Security默认将CSRF Token存储在HttpSession中,但你设置了SessionCreationPolicy.STATELESS,服务器不会创建或使用会话,因此无法生成和返回CSRF Token;
  • 所有非GET/HEAD/OPTIONS请求都会被CSRF过滤器拦截,哪怕是无需认证的请求,因为缺少有效的Token验证。

解决方案一:对公开接口跳过CSRF验证

如果部分非GET请求是公开接口(无需认证),可以直接跳过这些路径的CSRF校验,修改configure(HttpSecurity http)方法:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .csrf()
                .ignoringAntMatchers("/public/**", "/login") // 替换为你的公开非GET请求路径
                .and()
            .authorizeRequests()
                .antMatchers("/profile").authenticated()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .anyRequest().permitAll()
                .and()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .headers().frameOptions().disable()
            .and()
            .exceptionHandling()
                .authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));

    http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}

解决方案二:配置CSRF Token存储到Cookie(适合前后端分离场景)

如果需要对所有非GET请求做CSRF防护,可将CSRF Token存储到Cookie中,允许前端读取并在请求时携带,修改配置如下:

首先导入CookieCsrfTokenRepository:

import org.springframework.security.web.csrf.CookieCsrfTokenRepository;

然后修改configure(HttpSecurity http)中的CSRF配置:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .csrf()
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) // 允许前端读取Cookie
                .and()
            .authorizeRequests()
                .antMatchers("/profile").authenticated()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .anyRequest().permitAll()
                .and()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .headers().frameOptions().disable()
            .and()
            .exceptionHandling()
                .authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));

    http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}

前端配合处理

前端需要从Cookie中取出XSRF-TOKEN值,在非GET请求的请求头中添加X-XSRF-TOKEN,值为Cookie中的Token内容。例如:

  • 原生JS:从document.cookie中提取XSRF-TOKEN
  • Axios:框架会自动读取XSRF-TOKENCookie,并自动添加X-XSRF-TOKEN请求头

这样Spring Security会自动验证请求头中的Token与Cookie中的Token是否一致,完成CSRF防护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 11:02:22