简体   繁体   English

Spring Security,无状态REST服务和CSRF

[英]Spring Security, Stateless REST service and CSRF

I have a REST service, built using Java, Spring-boot and using Spring Security with Basic Access Authentication. 我有一个REST服务,它使用Java,Spring-boot和带有基本访问身份验证的Spring Security构建。 There are no Views, no JSP etc, no 'login', just stateless services which can be called from a React app hosted separately. 没有视图,没有JSP等,没有“登录”,只有可以从单独托管的React应用调用的无状态服务。

I've read a variety of documentation about CSRF protection, but can't decide whether I should be using spring-security CSRF config, or just disabling it? 我已经阅读了许多有关CSRF保护的文档,但是无法决定我应该使用spring-security CSRF配置还是仅禁用它? If I disable the csrf protection I can call the service with curl using my basic auth like this: 如果禁用csrf保护,则可以使用我的基本身份验证使用curl调用服务,如下所示:

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

If I enable the csrf protection and provide a x-csrf-token header, then the spring CsrfFilter attempts to cross check this against a value from (I think) a session cookie in the HttpServletRequest . 如果我启用了csrf保护并提供了x-csrf-token标头,则春季CsrfFilter会尝试根据HttpServletRequest的会话cookie(我认为)中的值进行交叉检查。 However since its a stateless REST service I don't have a session, and haven't 'logged in'. 但是,由于它是无状态的REST服务,所以我没有会话,也没有“登录”。

I have a config class which looks like this: 我有一个配置类,看起来像这样:

@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();
        }
    }

The more I think about it, the more it seems that I will just need to disable CSRF protection. 我考虑得越多,似乎越需要禁用CSRF保护。 Is there another way to configure spring security so it will work? 还有另一种配置spring安全性的方法,它可以工作吗?

thanks 谢谢

To answer your first question, in the context that you describe, you do not need CSRF protection. 要回答您的第一个问题,在您描述的上下文中,您不需要CSRF保护。 The background of CSRF protection is to ensure that the user is not tricked into doing some unwanted action. CSRF保护的背景是确保不会诱骗用户执行某些不必要的操作。

For example, in pure theory, you could have logged into a bank's website (and thus established a session) and then went to some shady website. 例如,按照纯粹的理论,您可能已经登录到银行的网站(因此建立了会话),然后访问了一些黑幕网站。 This site could have a form making a POST request to the bank's APIs. 该站点可以具有向银行的API发出POST请求的表单。 Because you have a session there, if the endpoint is not CSRF protected, then the request may go through. 因为那里有一个会话,所以如果端点不受CSRF保护,则该请求可能会通过。

As such, CSRF mostly acts as a protection against browser + session based attacks. 因此,CSRF主要充当针对基于浏览器+基于会话的攻击的防护。 If you expose a pure REST API with eg OAuth protection, then I don't see any reason for CSRF. 如果您公开了具有OAuth保护的纯REST API,那么我看不到CSRF的任何原因。

As you use spring boot, you could also disable CSRF using the application.properties / application.yaml configuration file. 使用Spring Boot时,还可以使用application.properties / application.yaml配置文件禁用CSRF。

security.enable-csrf=false

You can check out the Common Application Properties documentation page for more out-of-the-box configuration options. 您可以查看“ 通用应用程序属性”文档页面,以获取更多现成的配置选项。

If you want to disable csrf in more proper way you can call it like this(if using java configuration) 如果您想以更适当的方式禁用csrf,则可以这样调用(如果使用java配置)

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM