我正在使用Spring Security
该应用已启用以下内容:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/resources/css/**", "/resources/images/**", "/resources/jquery/**", "/resources/js/**").permitAll()
... more URLs to intercept
.antMatchers("/notification**").hasAuthority("ROLE_ADMIN")
.antMatchers("/ajax/notification**").hasAuthority("ROLE_ADMIN")
.anyRequest().authenticated()
.and()
.csrf()
...
观察CSRF
已应用。对于表格,使用以下内容:
<c:url var="logoutUrl" value="/logout"/>
<form action="${logoutUrl}"
method="post">
<input type="submit"
value="Log out" />
<input type="hidden"
name="${_csrf.parameterName}"
value="${_csrf.token}"/>
</form>
该应用程序运行良好如何预期,它会在加载/呈现jsp
页面之前拦截任何URL并要求登录控制如何预期,如果用户已记录有关授权的控件应用如何预计也是。因此,所有人都在使用CSRF
如何建议。
直到这里一切都好。
我在jQuery
添加了ajax,因为它适用于网址,因此我也需要为该网址应用CSRF
控件。
这就是上面出现的原因:
.antMatchers("/ajax/notification**").hasAuthority("ROLE_ADMIN")
现在,我希望在CSRF
应用于ajax网址"/ajax/notification"
时获取预期的 HTTP错误代码和消息 CSRF
标题不发送。
js ajax代码是:
$.getJSON(
"/projectname-01/ajax/notification",
function(data, textStatus, req) {
console.log("data: " + data);
console.log("textStatus: " + textStatus);
console.log("req: " + req)
console.log("data: " + data);
console.log(data.content + " " + data.date);
$("#single").empty();
$("#single").append(data.content + " " + data.date);
$("#multiple").append(data.content + " " + data.date)
.append("<br/>");
}
)
注意:网址必须为/projectname-01/ajax/notification
,projectname-01
是强制性的,如果删除,我会获得404
。即使使用./ajax/notification
它也不起作用(观察点)。
问题:代码工作正常,我的意思是,Ajax调用发生在服务器上没有任何问题,我期待一些错误,因为代码不使用CRSF
ajax的requeriments。
根据:
因此,例如:
<head>
<meta name="_csrf" content="${_csrf.token}"/>
<!-- default header name is X-CSRF-TOKEN -->
<meta name="_csrf_header" content="${_csrf.headerName}"/>
<!-- ... -->
</head>
或
<sec:csrfMetaTags />
当然js代码使用:
_csrf_parameter
,_csrf_header
等。
然后,出于测试和生产目的,需要预期的HTTP错误代码和消息
因此,缺少什么?或者问题是什么?
标头:HTTP标头下方请求的方式:
来自Opera
General
Request URL:http://localhost:8080/security-01/ajax/notification
Request Method:GET
Status Code:200
Remote Address:[::1]:8080
Referrer Policy:no-referrer-when-downgrade
Response Headers
HTTP/1.1 200
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Sat, 23 Sep 2017 00:14:20 GMT
Request Headers
GET /security-01/ajax/notification HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36 OPR/47.0.2631.80
Referer: http://localhost:8080/security-01/tiles/notification/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8
Cookie: JSESSIONID=9F2007DA3C8C683D26B8D17D85563140; jenkins-timestamper-offset=18000000
来自Firefox
Request Headers
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:8080/security-01/tiles/notification/
X-Requested-With: XMLHttpRequest
Cookie: JSESSIONID=CF344E56DD03C4019DCA334CD38B73EC
Connection: keep-alive
Response Header
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Sat, 23 Sep 2017 00:17:06 GMT
澄清
根据Spring Security Reference Documentation
,我们对CSRF
的{{1}}页面(提交表单)和申请JSP
,同时使用Ajax
{1}}。对于前者我已经配置并且工作正常。后者是问题。
当我使用URL
&#39; jQuery
来电而不时,会发送特殊的$.getJSON
值CSRF data/headers
,{{1} }等等,我的意思是:30.6 The csrfMetaTags Tag出现如下:
<sec:csrfMetaTags />
从上方发送来自meta[name='_csrf_parameter']
或 // using JQuery to send an x-www-form-urlencoded request
var data = {};
data[csrfParameter] = csrfToken;
data["name"] = "John";
...
$.ajax({
url: "http://www.example.org/do/something",
type: "POST",
data: data,
...
});
// using JQuery to send a non-x-www-form-urlencoded request
var headers = {};
headers[csrfHeader] = csrfToken;
$.ajax({
url: "http://www.example.org/do/something",
type: "POST",
headers: headers,
...
});
的{{1}}信息。但在我的代码中,我不发送它。因此,我希望通过CRSF
因此,使用我当前的ajax代码,通过在运行时开发(data
与app一起运行),对服务器的调用发生并返回数据。因此headers
没有拦截并因这些Spring Security
的缺席而引发错误。
因此,现在考虑进行开发和测试,如果我创建的Tomcat
方法应该失败,因为Spring Security
值不发送。 CRSF data/headers
方法将失败,因为调用服务器时没有任何安全性控件。
答案 0 :(得分:1)
您的HTTP GET
请求不会产生任何错误,因为只有更新状态的请求才需要CSRF令牌,请参阅Spring Security Reference:
18.2同步器令牌模式
[...]
我们可以放松期望,只需要更新状态的每个HTTP请求的令牌。这可以安全地完成,因为相同的原始策略确保恶意站点无法读取响应。此外,我们不希望在HTTP GET中包含随机令牌,因为这会导致令牌泄露。
使用同步器令牌模式应用CSRF保护。开发人员必须确保为允许状态更改的任何请求调用
CsrfFilter
。通常这只意味着他们应该确保他们的Web应用程序遵循正确的REST语义(即不要使用HTTP方法GET,HEAD,TRACE,OPTIONS来改变状态。)
要获取CSRF令牌,您必须使用HTTP POST
,PUT
或DELETE
请求。