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
Spring Security: enable / disable CSRF by client type (browser / non-browser )
提问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 /api
that 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 /api
hierachy 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, rootcontrollerurl
and request_part_url
may be blank ...)
(当然,rootcontrollerurl
也request_part_url
可能是空白……)
But youmust analyze the security implication of allowing non csrf controlled requests, and eventually exclude controllers from the /api
hierarchy.
但是您必须分析允许非 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 请求,则顺序很重要。