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]