Spring Security4 之 csrf

CSRF(Cross-site request forgery跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。为了防止跨站提交攻击,通常会配置csrf。

Spring Security 为了防止跨站提交攻击提供了CSRF保护功能,该功能在Spring Security 3时就已经存在,默认是不启用,Spring Security 4默认启用了,所以由Spring Security 3升级到Spring Security 4就会有所有POST方式请求的服务会调用失败的问题,原因在于:启用csrf后,所有http请求都被会CsrfFilter拦截,而CsrfFilter中有一个私有类DefaultRequiresCsrfMatcher。

private static final class DefaultRequiresCsrfMatcher implements RequestMatcher {

   private Pattern allowedMethods = Pattern.compile("^(GET|HEAD|TRACE|OPTIONS)$");

   /* (non-Javadoc)
    * @see org.springframework.security.web.util.matcher.RequestMatcher#matches(javax.servlet.http.HttpServletRequest)
   */
   public boolean matches(HttpServletRequest request) {
      return !allowedMethods.matcher(request.getMethod()).matches();
   }
}

从这段源码可以发现,POST方法被排除在外了,也就是说只有GET|HEAD|TRACE|OPTIONS这4类方法会被放行,其它Method的http请求,都要验证_csrf的token是否正确,而通常post方式调用rest服务时,又没有_csrf的token,所以校验失败。

 

如果想禁用CSRF保护功能,可采取以下方式:

Security XML配置文件中配置:

<csrf disabled="true" />

如果你使用JAVA注解配置:

@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http
      .csrf().disable();
  }
}

 

如果正常使用CSRF:

对于表单域,可增加一个标签<security:csrfInput/>,这个标签会生成一个隐藏域。

<%@ 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:csrfInput/>实际会生成<input type="hidden" name="_csrf" value="XXXXXXXXXXXXXXXXXXXX"> 

对于非表单域,增加<security:csrfMetaTags/>,该标签可在报文头增加crsf的token。

<%@ 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[name=_csrf_header]').attr('content');  
            var token  = $('meta[name=_csrf]').attr('content');   
            if (header != '' && token != ''){             
                xhr.setRequestHeader(header, token);  
            }  
        }  
    });  
})();  

 

转载于:https://my.oschina.net/shajin/blog/786930

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值