java Spring Security:按客户端类型启用/禁用 CSRF(浏览器/非浏览器)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26179940/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 09:27:02  来源:igfitidea点击:

Spring Security: enable / disable CSRF by client type (browser / non-browser )

javaspringspring-mvcspring-securitycsrf

提问by Himalay Majumdar

Spring Security documentation says:

Spring Security 文档

"When you use CSRF protection? Our recommendation is to use CSRF protection for any request that could be processed by a browser by normal users. If you are only creating a service that is used by non-browser clients, you will likely want to disable CSRF protection."

“当您使用 CSRF 保护时?我们的建议是对普通用户可以由浏览器处理的任何请求使用 CSRF 保护。如果您只创建非浏览器客户端使用的服务,您可能希望禁用CSRF 保护。”


What if my service is going to be used by both "browser" and "non-browser" clients such as third party external services, does Spring Security provide a way to disable CSRF exclusively for certain type of clients?


如果我的服务将同时被“浏览器”和“非浏览器”客户端(例如第三方外部服务)使用,Spring Security 是否提供了专门为某些类型的客户端禁用 CSRF 的方法?

采纳答案by Himalay Majumdar

I am sure there is a way to do this in Spring Security XML, but since I am using Java Config, here is my solution.

我确信在 Spring Security XML 中有一种方法可以做到这一点,但由于我使用的是 Java Config,因此这是我的解决方案。

 @Configuration
 @EnableWebSecurity
 public class SecurityConfig {

    @Configuration
    @Order(1)
    public static class SoapApiConfigurationAdapter extends WebSecurityConfigurerAdapter {
        protected void configure(HttpSecurity http) throws Exception {
            http
                .antMatcher("/soap/**")
                .csrf().disable()
                .httpBasic();
        }
    }


    @Configuration
    public static class WebApiConfigurationAdapter extends WebSecurityConfigurerAdapter {

        protected void configure(HttpSecurity http) throws Exception {
            http        
                .formLogin()
                    .loginProcessingUrl("/authentication")
                    .usernameParameter("j_username")
                    .passwordParameter("j_password").permitAll()
                    .and()
                .csrf().disable()

        }
     }
}

回答by Serge Ballesta

IMHO, there is nothing like that out of the box. What I would do in your case, is to have a hierarchy of URL for example rooted at /apithat would be exempt of csrf. It is easy to configure. In the XML config, you have a normal <http>block including <csrf/>, you just duplicate it and modify the first block like that

恕我直言,没有什么是开箱即用的。在您的情况下,我会做的是拥有一个 URL 层次结构,例如根植于/api该层次结构,将免除 csrf。很容易配置。在 XML 配置中,您有一个普通的<http>块,包括<csrf/>,您只需复制它并像这样修改第一个块

<http pattern="/api/**">
    ...
    <!-- csrf -->
</http>

As it is first, it will be triggered for any request to /apihierachy without using csrf, and all other requests will use it.

由于它是第一个,它将在/api不使用 csrf 的情况下为任何层次结构请求触发,所有其他请求都将使用它。

In the normal part of the application, you never use the /api/**url, and reserve them to non-browser usages.

在应用程序的正常部分,您从不使用/api/**url,并将它们保留给非浏览器使用。

Then in your controllers, you map them to both their normal url and a copy under /api:

然后在您的控制器中,您将它们映射到它们的正常 url 和下的副本/api

@Controller
@RequestMapping({ "/rootcontrollerurl", "/api/rootcontrollerurl"})
class XController {
    @RequestMapping(value = "/request_part_url", ...)
    public ModelAndView method() {
        ...
    }
}

(of course, rootcontrollerurland request_part_urlmay be blank ...)

(当然,rootcontrollerurlrequest_part_url可能是空白……)

But youmust analyze the security implication of allowing non csrf controlled requests, and eventually exclude controllers from the /apihierarchy.

但是必须分析允许非 csrf 控制的请求的安全含义,并最终从/api层次结构中排除控制器。

回答by Jelqui

Here is what I used to disable the CSRF protection on an specific endpoint on your appconfig-security.xml add a node with the information of your pattern like the following example:

这是我用来在 appconfig-security.xml 上的特定端点上禁用 CSRF 保护的内容,添加一个包含您的模式信息的节点,如下例所示:

<http security="none" pattern="/sku/*"/>
<http security="none" pattern="/sku/*/*"/>
<http security="none" pattern="/sku"/>

Just keep in mind the order is important if you are going to use map all request using the symbol '*' goes first.

请记住,如果您要使用符号“*”首先使用 map all 请求,则顺序很重要。