我有一个 Spring Boot REST API。由于安全策略的原因,我需要为浏览器访问的端点启用 CSRF 保护。但是,非浏览器也可以访问此 API。有没有办法创建两组端点,一组只能在启用 CSRF 的情况下由浏览器访问,另一组只能在禁用 CSRF 的情况下由非浏览器访问?
当您使用 DSL 配置 CSRF 保护时,如下所示
http.csrf()...
,您可以通过传递 RequestMatcher
来判断您希望应用 CSRF 保护的请求,如下所示:
http.csrf(csrf -> csrf.requireCsrfProtectionMatcher(new MyBrowserRequestMatcher()));
您的
RequestMatcher
实现可以验证HttpServletRequest
是否包含标题X-Requested-With: XMLHttpRequest
或检查User-Agent
。
请记住,标头可以更改,并且您不能保证请求实际上来自浏览器或非浏览器应用程序。
在 Spring Security 配置中:
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.csrf().ignoringAntMatchers("/withoutCsrf/**")
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.cors().disable();
//complete your configuration }
在控制器中:
@Controller
@RequestMapping({"books","withoutCsrf/books"})
public class BookController {}
创建 SecurityFilterChain 时可以禁用对特定 URL 的 CSRF 保护。
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
httpSecurity.csrf((csrf) -> csrf.ignoringRequestMatchers("/trade/item/nxtitems", "/trade/item/**")).build();
}