Spring 安全 CSRF 令牌不适用于 AJAX
Spring Security CSRF Token not working with AJAX
我的 spring 引导应用程序中的 csrf 令牌有问题。
我有一个可以编辑人物的表格。一个人可以拥有
现在让我们想象这个人有一辆车,然后输入并存储它。下次他要删除这辆车并输入另一辆车。我已经创建了它,以便有一个包含他所有汽车的列表——他可以选择将其从列表中删除。现在我从这些药丸开始,想用相应的 ID 发送到服务器 a POST。当我尝试时,我得到了 403 禁止,我不知道为什么。
如果我从 POST 更改为 GET,那么就可以了。
我的 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,
});
我的控制器方法:
@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);
}
有什么建议吗?
提前致谢。
好的,经过所有这些努力之后,我得到了以下结果。
我将 fail
方法添加到 Ajax 构造并得到以下消息:
"Failed to execute 'setRequestHeader' on 'XMLHttpRequest': '${_csrf.headerName}' is not a valid HTTP header field name."
官方 spring 站点建议您必须将此 <sec:csrfMetaTags />
或来自其他来源的此 <meta name="_csrf" th:content="${_csrf.token}"/>
放入您的 html 文件中。
在此之后,您应该能够在 JavaScript 中访问这些属性,但在我的情况下,我得到 undefined
和 ${_csrf.headerName}
。
最后一次尝试是从隐藏值中获取值(第 24.5 章:http://docs.spring.io/autorepo/docs/spring-security/4.0.0.CI-SNAPSHOT/reference/htmlsingle/#the-csrfmetatags-tag)。
现在,我有以下内容:
$(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);
}
});
有了这个,它就像一个魅力。
另一种方式,可以使用下面的代码:
$.ajax({
url : './delete/car',
headers: {"X-CSRF-TOKEN": $("input[name='_csrf']").val()},
type : 'POST',
success : function(result) {
alert(result.msgDetail);
}
})
我建议您首先检查是否使用 chrome 调试器生成了有效的 csrf 令牌和 header。如果没有,那么您是否在 <head>
中添加了 <sec:csrfMetaTags />
?(您将需要导入 spring 安全标签库)。如果使用 Apache tiles,则必须将其添加到用于视图的模板文件的 <head>
部分。
如果令牌不为空,那么在您的 security-context/configuration 文件中,检查您是否禁用了 csrf 安全性。默认情况下它是启用的,需要启用此过程才能工作。
我的 spring 引导应用程序中的 csrf 令牌有问题。
我有一个可以编辑人物的表格。一个人可以拥有
现在让我们想象这个人有一辆车,然后输入并存储它。下次他要删除这辆车并输入另一辆车。我已经创建了它,以便有一个包含他所有汽车的列表——他可以选择将其从列表中删除。现在我从这些药丸开始,想用相应的 ID 发送到服务器 a POST。当我尝试时,我得到了 403 禁止,我不知道为什么。
如果我从 POST 更改为 GET,那么就可以了。
我的 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,
});
我的控制器方法:
@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);
}
有什么建议吗?
提前致谢。
好的,经过所有这些努力之后,我得到了以下结果。
我将 fail
方法添加到 Ajax 构造并得到以下消息:
"Failed to execute 'setRequestHeader' on 'XMLHttpRequest': '${_csrf.headerName}' is not a valid HTTP header field name."
官方 spring 站点建议您必须将此 <sec:csrfMetaTags />
或来自其他来源的此 <meta name="_csrf" th:content="${_csrf.token}"/>
放入您的 html 文件中。
在此之后,您应该能够在 JavaScript 中访问这些属性,但在我的情况下,我得到 undefined
和 ${_csrf.headerName}
。
最后一次尝试是从隐藏值中获取值(第 24.5 章:http://docs.spring.io/autorepo/docs/spring-security/4.0.0.CI-SNAPSHOT/reference/htmlsingle/#the-csrfmetatags-tag)。
现在,我有以下内容:
$(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);
}
});
有了这个,它就像一个魅力。
另一种方式,可以使用下面的代码:
$.ajax({
url : './delete/car',
headers: {"X-CSRF-TOKEN": $("input[name='_csrf']").val()},
type : 'POST',
success : function(result) {
alert(result.msgDetail);
}
})
我建议您首先检查是否使用 chrome 调试器生成了有效的 csrf 令牌和 header。如果没有,那么您是否在
<head>
中添加了<sec:csrfMetaTags />
?(您将需要导入 spring 安全标签库)。如果使用 Apache tiles,则必须将其添加到用于视图的模板文件的<head>
部分。如果令牌不为空,那么在您的 security-context/configuration 文件中,检查您是否禁用了 csrf 安全性。默认情况下它是启用的,需要启用此过程才能工作。