Spring Security 默认会启用 CSRF 防护,此时需要在请求中通过参数或请求头传入 CSRF token,否则服务端会报错。因此,如果用接口调试工具调试对应的接口,就需要一些特殊设置。
public class AuthenticationManagerConfig {
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers("/login","/hello").permitAll()
.anyRequest().authenticated()
)
.csrf(csrf -> csrf
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.csrfTokenRequestHandler(new CsrfTokenRequestAttributeHandler())
);
return http.build();
}
}
这里的.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())是为了让服务端在需要的时候(登录、POST\PUT 请求时)返回报文的 Cookie 中添加 CSRF token,这样客户端就可以将该 token 保存并在请求中使用。
.csrfTokenRequestHandler(new CsrfTokenRequestAttributeHandler())是为了兼容性,Spring Boot 3.X 之后,为了安全性,默认不允许客户端直接将服务端返回的 token 发送给服务端,而是需要客户端进一步加密后再发送,因此,如果需要直接发送 token 原文,就需要这种兼容性设置。
当客户端请求时缺少 CSRF token,服务端默认返回的报文状态码是 403,可以在客户端添加执行后脚本,如果出现这种情况,就将返回报文的 CSRF token 保存到环境变量中:
if(pm.response.code='403'){
let token = pm.response.cookies.get('XSRF-TOKEN');
console.log(token);
pm.environment.set('csrf-token', token);
console.log("csrf token 已写入环境变量");
}
为了方便在每一个需要的接口中添加,可以将该脚本添加到脚本库中。
添加全局参数,使用该环境变量作为 Header:

现在再请求就 OK 了。
The End.

文章评论