Spring 安全、无状态 REST 服务和 CSRF

Spring Security, Stateless REST service and CSRF

我有一个 REST 服务,使用 Java、Spring-boot 构建并使用 Spring 安全和基本访问身份验证。没有视图,没有 JSP 等,没有 'login',只有可以从单独托管的 React 应用程序调用的无状态服务。

我已经阅读了各种关于 CSRF 保护的文档,但无法决定我是否应该使用 spring-security CSRF 配置,或者只是禁用它?如果我禁用 csrf 保护,我可以使用我的基本身份验证通过 curl 调用服务,如下所示:

curl -H "authorization:Basic c35sdfsdfjpzYzB0dDFzaHA=" -H "content-type:application/json" -d '{"username":"user","password":"password","roles":"USER"}' localhost:8081/api/v1/user

如果我启用 csrf 保护并提供 x-csrf-token header,那么 spring CsrfFilter 会尝试将其与来自(我认为)[=35 的值进行交叉检查=] HttpServletRequest 中的 cookie。但是,由于它是无状态 REST 服务,我没有 session,也没有 'logged in'。

我的配置 class 如下所示:

@EnableWebSecurity
@Configuration
public class ServiceSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest().fullyAuthenticated()
                .and().httpBasic();
        if (!serviceProperties.isCsrfEnabled()) {
            http.csrf().disable();
        }
    }

我越想越觉得我只需要禁用 CSRF 保护即可。是否有另一种方法来配置 spring 安全性以使其起作用?

谢谢

回答你的第一个问题,在你描述的上下文中,你不需要 CSRF 保护。 CSRF 保护的背景是确保用户不被诱骗去做一些不受欢迎的行为。

例如,在纯理论中,您可能已经登录到一家银行的网站(并因此建立了一个会话),然后去了一些可疑的网站。该网站可以有一个表格,向银行的 API 提出 POST 请求。因为你在那里有一个会话,如果端点不受 CSRF 保护,那么请求可能会通过。

因此,CSRF 主要用于防止基于浏览器+会话的攻击。如果您使用例如公开纯 REST API OAuth 保护,那么我看不出任何 CSRF 的理由。

当您使用 spring 引导时,您还可以使用 application.properties / application.yaml 配置文件禁用 CSRF。

security.enable-csrf=false

您可以查看 Common Application Properties 文档页面以了解更多 out-of-the-box 配置选项。

如果你想以更合适的方式禁用 csrf,你可以这样调用它(如果使用 java 配置)

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
            .anyRequest().fullyAuthenticated()
            .and().httpBasic();
       .and()
            .csrf()
            .disable()