工作中遇到的问题,这里记录下,也希望能够帮助同学们少走弯路
为了快速帮助快速解决问题,我决定首先呈现问题的表现,再进行分析
环境:spring 4.2.3
spring security 4.1.3
表现:
2016-10-26 22:44:02 [http-apr-9080-exec-10] DEBUG org.springframework.security.web.csrf.CsrfFilter - Invalid CSRF token found for XXX
2016-10-26 22:44:02 [http-apr-9080-exec-10] DEBUG org.springframework.security.web.header.writers.HstsHeaderWriter - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@c3339ef
2016-10-26 22:44:02 [http-apr-9080-exec-10] DEBUG org.springframework.security.web.context.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
前台使用AJAX向后台传输数据时候控制台报出上述错误,再未集成Spring Security时不会出现此现象
解决方法:
如果前端使用的JSP
可以在前端页面的<head>标签中增加两个<meta>标签
如下
<html> <head> <meta name="_csrf" content="${_csrf.token}"/> <!-- default header name is X-CSRF-TOKEN --> <meta name="_csrf_header" content="${_csrf.headerName}"/> <!-- ... --> </head>
如果前端使用的是Thymeleaf分两种情况
1.前端无form表单,也要再头部增加两个meta标签,形式为
<html> <head> <meta name="_csrf" th:content="${_csrf.token}" content=""/> <!-- default header name is X-CSRF-TOKEN --> <meta name="_csrf_header" th:content="${_csrf.headerName}" content=""/> <!-- ... --> </head>
2.前端有form表单
Spring Security为Thymeleaf中的表单中自动添加一个<input type="hidden" name = "_csrf" value="xxxxxxxxxx"> (xxxx为crrf.token)
添加完meta之后不妨运行下,在页面代码中搜索_csrf,可以看看附近代码的样子,应该就会明白了
这样在使用AJAX时,需要增加一个头部
var token = $("meta[name='_csrf']").attr("content"); var header = $("meta[name='_csrf_header']").attr("content");
$.ajax({ type: "POST", url: "myposturl", data: entID, contentType:"application/json; charset=utf-8", headers : {header:token}, async:false, success:function(data){ //do something }, error: function () { //deal width error } });实际上,这里的header使用为值"X-CSRF-TOKEN" 这样就可以成功向后台请求了