Spring Boot REST API - 按客户端类型(浏览器/非浏览器)启用/禁用 CSRF 保护?

问题描述 投票:0回答:4

我有一个 Spring Boot REST API。由于安全策略的原因,我需要为浏览器访问的端点启用 CSRF 保护。但是,非浏览器也可以访问此 API。有没有办法创建两组端点,一组只能在启用 CSRF 的情况下由浏览器访问,另一组只能在禁用 CSRF 的情况下由非浏览器访问?

java spring-boot rest spring-security csrf
4个回答
2
投票

当您使用 DSL 配置 CSRF 保护时,如下所示

http.csrf()...
,您可以通过传递
RequestMatcher
来判断您希望应用 CSRF 保护的请求,如下所示:

http.csrf(csrf -> csrf.requireCsrfProtectionMatcher(new MyBrowserRequestMatcher()));

您的

RequestMatcher
实现可以验证
HttpServletRequest
是否包含标题
X-Requested-With: XMLHttpRequest
或检查
User-Agent

请记住,标头可以更改,并且您不能保证请求实际上来自浏览器或非浏览器应用程序。


0
投票

我认为您可以为浏览器请求和 API 请求拥有单独的 URL 库。

例如,您可以在

/api/...
下拥有非浏览器要查询的所有端点,并且在您的
SpringBootSecurityConfiguration
类和
configure(HttpSecurity http)
方法中,如果模式匹配,您可以使用
http.csrf().disable();
有条件地禁用 CSRF(非常好)教程可以在这里找到

编辑:这是另一个可能有用的

答案


0
投票
正如 @ferrouskid 所说,我创建了两个 URL,一个用于浏览器,另一个用于非浏览器:

在 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 {}
    

0
投票
由于依赖请求头可能无法准确识别请求来源,因此创建单独的服务 url,一个用于浏览器客户端,一个用于非浏览器客户端,并对非浏览器服务禁用 CSRF 保护也可以考虑作为一种解决方案。

创建 SecurityFilterChain 时可以禁用对特定 URL 的 CSRF 保护。

@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { httpSecurity.csrf((csrf) -> csrf.ignoringRequestMatchers("/trade/item/nxtitems", "/trade/item/**")).build(); }
    
© www.soinside.com 2019 - 2024. All rights reserved.