spring security(三)

第一部分.csrf问题会导致ajax请求失败,原因是没有验证csrf的token。具体流程是启用csrf后,所有http请求都被会CsrfFilter拦截,而CsrfFilter中有一个私有类DefaultRequiresCsrfMatcher ,在这个类里面,POST方法被排除在外了,也就是说只有GET|HEAD|TRACE|OPTIONS这4类方法会被放行,其它Method的http请求,都要验证_csrf的token是否正确,而通常post方式调用rest服务时,又没有_csrf的token,所以校验失败。具体方法是重写一个Matcher,当请求为POST请求时添加一个排除校验的url列表。

解决办法:

1、在jsp页面的head标签内添加如下代码:
<meta name="_csrf" content="${_csrf.token}"/>
<!-- default header name is X-CSRF-TOKEN -->
<meta name="_csrf_header" content="${_csrf.headerName}"/>

2、在ajax请求前添加如下代码:
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
$(document).ajaxSend(function(e, xhr, options) {
xhr.setRequestHeader(header, token);
});

等同下面:

var header = $("meta[name='_csrf_header']").attr("content"); 

 var token = $("meta[name='_csrf']").attr("content");   

  $.ajax({     

 url: '/test',      

type: 'POST',      

beforeSend: function(xhr){          

xhr.setRequestHeader(header, token);      

},      

success: function(data) {          

console.log(data);   

},  

error:function(xhr,ajaxOptions, thrownError) { console.log(xhr.status + ": " + thrownError);  

 }  });

 

<sec:csrfMetaTags/> 

等同于:

<head><meta name="_csrf" content="${_csrf.token}"/><meta name="_csrf_header" content="${_csrf.headerName}"/></head>  

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)

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"

第二部分:验证码部分,在登陆过程中可能会加入验证码验证,此时需要做出一些改变。

第一种:自定义一个过滤器,工作在spring security的过滤器前面实现验证码的较验。

第二种:写一个filter,继承UsernamePasswordAuthenticationFilter,重写attemptAuthentication方法实现验证码的校验,若校验不成功抛出异常。

第三种:替换UsernamePasswordAuthenticationFilter这个filter来自定义校验。

 

 

 

 

转载于:https://my.oschina.net/u/3667353/blog/1608930

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值