admin 发表于 2016-7-22 13:37

spring security 4 request parameter '_csrf' or header 'X-CSRF-TOKEN'.

最近配置 spring security 4登陆,感觉终于配置好了,居然出现HTTP Status 403 - Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.
原来spring security4增加了csrf, 而且默认是启用的,所以如果你是auto-config="true",那么就已经启用了csrf,
在http节点中可以对其进行配置
<security:csrf/>

所以意味着页面提交的信息中需要包含csrf的token, 如果是从spring security3签约过来很容易在这里被绊倒
请求的验证匹配规则,官网是这样的

The RequestMatcher instance to be used to determine if CSRF should be applied. Default is any HTTP method except "GET", "TRACE", "HEAD", "OPTIONS"
所以对post,put, 一定跳不过

csrf过滤器验证两项内容,报文头:Request Headers;提交数据:Form Data

实现代码

login.jsp



<%@ taglib prefix='security' uri='http://www.springframework.org/security/tags' %>
....

<form action="login" class="login-form" method="post" style="display: inline-table;">
        。。。
   <security:csrfInput/>
   <button type="submit" class="btn btn-success btn-block">登 录</button>
</form>
这里使用了security的一个标签,实际会生成

<input type="hidden" name="_csrf" value="XXXXXXXXXXXXXXXXXXXX">如果非表单提交会就会遇到麻烦,不可能为每次提交都加这么一个隐藏域
可以在报文头增加crsf的token,已jQuery为例

首先修改页面

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<%@ taglib prefix='security' uri='http://www.springframework.org/security/tags' %>
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="utf-8">
    <title>首页</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <security:csrfMetaTags/>
。。。。。。
这个标签会生成

    <meta name="_csrf_parameter" content="_csrf" />
    <meta name="_csrf_header" content="X-CSRF-TOKEN" />
    <meta name="_csrf" content="XXXXXXXXXXXXXXXXXX" />
然后写一个统一的jquery提交的处理

(function(){
        $(document).ajaxSend(function(e,xhr,opt) {
                if (opt.type == "POST"){
                        var header = $('meta').attr('content');
                        var token= $('meta').attr('content');
                        if (header != '' && token != ''){                       
                                xhr.setRequestHeader(header, token);
                        }
                }
        });
})();



页: [1]
查看完整版本: spring security 4 request parameter '_csrf' or header 'X-CSRF-TOKEN'.