Spring Security CSRF Token不使用AJAX

时间:2015-01-08 07:19:46

标签: java ajax spring spring-mvc csrf

我的春季启动应用中遇到了csrf令牌的问题。

我有一个表格,我可以编辑一个人。一个人可以拥有

现在让我们想象一下这个人有一辆车然后进入并储存它。下次他想删除这辆车并进入另一辆车。我创建了这个,以便列出他所有的汽车 - 他可以选择从列表中删除它。现在我从这些药片开始,并希望使用相应的ID向服务器发送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);
    }

有什么建议吗?

提前致谢。

3 个答案:

答案 0 :(得分:17)

好的,在经历了这一切之后,我得到了以下结果。

我将fail方法添加到Ajax构造中并获得以下消息:

  

"无法执行' setRequestHeader' on' XMLHttpRequest':' $ {_ csrf.headerName}'不是有效的HTTP标头字段名称。"

官方的春季网站建议你必须把这个:<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);
    }
});

这就像魅力一样。

答案 1 :(得分:3)

另一种方法,您可以使用以下代码:

$.ajax({
    url : './delete/car',
    headers: {"X-CSRF-TOKEN": $("input[name='_csrf']").val()},
    type : 'POST',
    success : function(result) {
        alert(result.msgDetail);
    }
})

答案 2 :(得分:0)

  1. 我建议您首先检查是否使用chrome调试器生成了有效的csrf令牌和标头。如果没有,那么您是否在<sec:csrfMetaTags />中添加了<head>?(您需要导入spring security taglibs)。如果使用Apache磁贴,则必须在用于视图的模板文件的<head>部分添加它。

  2. 如果令牌不为空,则在您的安全上下文/配置文件中,检查您是否已经禁用了csrf安全性。默认情况下,它已启用,需要此过程才能正常工作。