java Spring Security CSRF 令牌不适用于 AJAX
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27834867/
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 CSRF Token not working with AJAX
提问by Manu Zi
I have a problem in my spring boot app with the csrf token.
我的 Spring Boot 应用程序中的 csrf 令牌有问题。
I have a form where I can edit a Person. A Person can have
我有一个表单,我可以在其中编辑一个人。一个人可以有
Let us now imagine that the person has a car and enter this and store it. The next time he wants to delete this car and enter another one. I have created that so that there is a list of all of his cars -- he has the option to remove this from the list. Now I'm starting from these pills and want to send with the corresponding ID to the server a POST. When I try I get a 403 forbidden and I have no idea why.
现在让我们想象一下,这个人有一辆车,输入它并存放它。下次他想删除这辆车并输入另一辆车。我创建了它,以便有他所有汽车的列表——他可以选择从列表中删除它。现在我从这些药丸开始,想用相应的 ID 向服务器发送一个 POST。当我尝试时,我收到 403 禁止,我不知道为什么。
If I change from POST to GET, then it works.
如果我从 POST 更改为 GET,则它可以工作。
My JavaScript (taken from this site: http://docs.spring.io/autorepo/docs/spring-security/4.0.0.CI-SNAPSHOT/reference/htmlsingle/#the-csrfmetatags-tag)
我的 JavaScript(取自本网站:http: //docs.spring.io/autorepo/docs/spring-security/4.0.0.CI-SNAPSHOT/reference/htmlsingle/#the-csrfmetatags-tag)
var csrfParameter = $("meta[name='_csrf_parameter']").attr("content");
var csrfHeader = $("meta[name='_csrf_header']").attr("content");
var csrfToken = $("meta[name='_csrf']").attr("content");
// using JQuery to send a non-x-www-form-urlencoded request
var headers = {};
headers[csrfHeader] = csrfToken;
$.ajax({
url: "./delete/car",
type: "GET",
headers: headers,
});
$.ajax({
url: "./delete/car",
type: "POST",
headers: headers,
});
My controller methods:
我的控制器方法:
@RequestMapping(value = "/{login}/delete/car", method = RequestMethod.GET)
public ModelAndView delete(@PathVariable("login") final String login) {
System.out.println("Stop");
return new ModelAndView("redirect:" + WebSecurityConfig.URL_PERSONS_OVERVIEW);
}
@RequestMapping(value = "/{login}/delete/car", method = RequestMethod.POST)
public ModelAndView deleteInstEmp(@PathVariable("login") final String login) {
System.out.println("Stop");
return new ModelAndView("redirect:" + WebSecurityConfig.URL_PERSONS_OVERVIEW);
}
Any suggestions?
有什么建议?
Thanks in advance.
提前致谢。
回答by Manu Zi
OK, after strugglin with all that, I get the following result.
好的,经过所有这些努力之后,我得到了以下结果。
I added the fail
method to the Ajax construct and get the following message:
我将该fail
方法添加到 Ajax 构造中并得到以下消息:
"Failed to execute 'setRequestHeader' on 'XMLHttpRequest': '${_csrf.headerName}' is not a valid HTTP header field name."
“无法在 'XMLHttpRequest' 上执行 'setRequestHeader':'${_csrf.headerName}' 不是有效的 HTTP 标头字段名称。”
the official spring site advises that you have to put this: <sec:csrfMetaTags />
or from other sources, this: <meta name="_csrf" th:content="${_csrf.token}"/>
in your html file.
spring 官方网站建议您必须将 this:<sec:csrfMetaTags />
或来自其他来源的 this:<meta name="_csrf" th:content="${_csrf.token}"/>
放在您的 html 文件中。
After this, you should be able to access these attributes in your JavaScript, but in my case I get undefined
and ${_csrf.headerName}
.
在此之后,您应该能够在您的 JavaScript 中访问这些属性,但在我的情况下,我得到undefined
和${_csrf.headerName}
.
A last try was to take the value from the hidden value (chapter 24.5: http://docs.spring.io/autorepo/docs/spring-security/4.0.0.CI-SNAPSHOT/reference/htmlsingle/#the-csrfmetatags-tag).
最后一次尝试是从隐藏值中获取值(第 24.5 章:http: //docs.spring.io/autorepo/docs/spring-security/4.0.0.CI-SNAPSHOT/reference/htmlsingle/#the-csrfmetatags -标签)。
Now, I have the following:
现在,我有以下几点:
$(function () {
var token = $("input[name='_csrf']").val();
var header = "X-CSRF-TOKEN";
$(document).ajaxSend(function(e, xhr, options) {
xhr.setRequestHeader(header, token);
});
});
$.ajax({
url: "./delete/car",
type: "POST",
success:function(response) {
alert(response);
}
});
With this it works like a charm.
有了这个,它就像一个魅力。
回答by Huy Quang
Another way, you can use the following code:
另一种方法,您可以使用以下代码:
$.ajax({
url : './delete/car',
headers: {"X-CSRF-TOKEN": $("input[name='_csrf']").val()},
type : 'POST',
success : function(result) {
alert(result.msgDetail);
}
})
回答by Sameer Khanal
I suggest you first check if a valid csrf token and the header have been generated using chrome debugger. If not, then have you added the
<sec:csrfMetaTags />
in the<head>
?(you will need to import the spring security taglibs). If using Apache tiles, you will have to add this at the<head>
section of the template file being used for the view.If the token is not empty, then in your security-context/configuration file, check if you have disabled csrf security by any chance. By default it is enabled and needs to be for this process to work.
我建议您首先检查是否使用 chrome 调试器生成了有效的 csrf 令牌和标头。如果没有,那么您是否
<sec:csrfMetaTags />
在<head>
? 中添加了?(您将需要导入 spring 安全标签库)。如果使用 Apache 切片,则必须在<head>
用于视图的模板文件部分添加它。如果令牌不为空,则在您的安全上下文/配置文件中,检查是否有任何机会禁用了 csrf 安全性。默认情况下它是启用的,并且需要启用此过程才能正常工作。