Spring Security在REST应用中未发送CSRF Token问题求助
Spring Security CSRF Token未生成问题排查与解决
1. 先检查核心Spring Security配置
确保你的Security配置类里正确配置了CookieCsrfTokenRepository,尤其注意开启前端可读取Cookie的权限:
@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .csrf(csrf -> csrf // 必须加withHttpOnlyFalse(),否则Angular读不到Cookie里的Token .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) ) .authorizeHttpRequests(auth -> auth // 确保/home允许匿名访问,不然首次请求会被跳转到登录页,拿不到Token .requestMatchers("/home").permitAll() .anyRequest().authenticated() ); return http.build(); } }
这里最容易踩的坑就是忘了withHttpOnlyFalse()——如果HttpOnly设为true,前端JS无法读取这个Cookie,Angular自然没法把Token放到请求头里。
2. 确认Token生成的触发条件
Spring Security默认不会在无状态的GET请求中主动生成CSRF Token,因为GET请求本身不需要CSRF校验。要让/home返回Token,有两种办法:
- 先发起一个POST/PUT/DELETE请求(这类请求需要CSRF校验),此时Spring会自动在响应头里设置
XSRF-TOKENCookie; - 手动让GET请求触发Token生成,你可以在控制器里显式获取并暴露Token:
@GetMapping("/home") public String home(HttpServletRequest request) { // 获取当前的CSRF Token,Spring会自动生成如果不存在的话 CsrfToken csrfToken = (CsrfToken) request.getAttribute(CsrfToken.class.getName()); // 这里不需要手动设置Cookie,CookieCsrfTokenRepository会自动处理 return "home"; }
3. 排查Angular端的配置细节
Angular的HttpClient默认会自动处理CSRF,但要确保:
- 所有请求都带上
withCredentials: true,示例:
this.http.get('/home', { withCredentials: true }).subscribe(res => { // 处理响应 });
- 前后端域名/端口一致,或者Spring端正确配置了CORS允许携带凭证(见下一步)。
4. 跨域场景下的CORS配置
如果前后端是跨域部署(比如Spring在8080,Angular在4200),Spring端必须配置CORS允许携带Cookie:
@Configuration public class CorsConfig { @Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); // 这里必须填你Angular的实际地址,不能用*,否则allowCredentials会失效 config.addAllowedOrigin("http://localhost:4200"); config.addAllowedHeader("*"); config.addAllowedMethod("*"); source.registerCorsConfiguration("/**", config); return new CorsFilter(source); } }
5. 浏览器调试快速定位问题
打开浏览器F12的「网络」标签,查看/home请求的响应:
- 检查响应头里有没有
Set-Cookie: XSRF-TOKEN=xxxx; Path=/; HttpOnly=false; - 如果没有,看请求是不是被302重定向到登录页了——这说明你的
/home没被允许匿名访问; - 检查Cookie的域名、路径是否和当前请求匹配,避免Cookie无法被前端读取。
内容的提问来源于stack exchange,提问作者rborisov
相关产品推荐
相关产品推荐

