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

Spring Boot 3中如何重写Spring Security的CSRF生成逻辑?

Spring Boot 3.x 自定义 CSRF Token 生成逻辑失效问题解决

问题核心原因

  1. 包路径变更:Spring Boot 3.x 基于 Jakarta EE,所有 Servlet 相关类从 javax.servlet.http 迁移到了 jakarta.servlet.http,自定义实现类必须使用新包路径,否则会因类不兼容导致逻辑不生效。
  2. 默认校验规则:Spring Security 6.x(对应 Boot 3.x)默认不对 GET/HEAD/TRAC/OPTIONS 请求做 CSRF 校验,因此访问 GET 接口 /hello 时不会触发 loadToken 方法,这是框架默认行为,而非代码失效。

分步解决方案

1. 修正自定义 Repository 的包依赖与实现

确保 CustomCsrfTokenRepository 导入正确的 Jakarta Servlet 包,同时补全方法的有效返回值(原代码中 generateToken 无返回值会导致编译错误):

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.security.web.csrf.DefaultCsrfToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CustomCsrfTokenRepository implements CsrfTokenRepository {
    private static final Logger log = LoggerFactory.getLogger(CustomCsrfTokenRepository.class);

    @Override
    public CsrfToken generateToken(HttpServletRequest request) {
        log.info("执行 generateToken");
        // 返回标准 CsrfToken 实例,可自定义 Token 值与头部名称
        return new DefaultCsrfToken("X-CSRF-TOKEN", "_csrf", "custom-generated-token");
    }

    @Override
    public void saveToken(CsrfToken token, HttpServletRequest request, HttpServletResponse response) {
        log.info("执行 saveToken");
        // 实现 Token 持久化逻辑,比如存入 Session 或 Cookie
    }

    @Override
    public CsrfToken loadToken(HttpServletRequest request) {
        log.info("执行 loadToken");
        // 实现 Token 读取逻辑,从存储介质中获取
        return null; // 根据实际业务返回对应 Token
    }
}

2. 按需调整 CSRF 校验规则

如果需要让 GET 请求也触发 CSRF 校验(默认不触发),可在 Security 配置中自定义校验匹配器;若仅需校验修改类请求(POST/PUT/DELETE),则保持默认规则即可。

配置示例(包含 GET 校验):

@Configuration
@EnableWebSecurity
public class ProjectConfig {

    @Bean
    public CsrfTokenRepository customTokenRepository() {
        return new CustomCsrfTokenRepository();
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .csrf(csrf -> csrf
                        .csrfTokenRepository(customTokenRepository())
                        // 自定义需要校验的请求方法,这里包含 GET
                        .requireCsrfProtectionMatcher(request -> {
                            String method = request.getMethod();
                            return "GET".equals(method) || "POST".equals(method) || "PUT".equals(method) || "DELETE".equals(method);
                        })
                )
                .authorizeHttpRequests(auth -> auth
                        .anyRequest().permitAll()
                );
        return http.build();
    }
}

3. 验证逻辑有效性

  • 若使用默认规则:测试 POST/PUT/DELETE 请求,此时会自动触发 CSRF 校验,自定义 Repository 的 loadToken 等方法会执行。
  • 若配置了 GET 校验:访问 /hello GET 接口时,loadToken 方法会被调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 21:37:35