spring security 防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保护功能相关操作

2.1如何禁用?

2.1.1Security XML配置文件中配置:

<csrf disabled="true" />

2.1.2如果你使用Java configuration配置:

@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

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

 

2.2如何启用?

说明:前面介绍中以经说了,spring4.0默认是开启的,所以只需要在前端页面配置CSRF_token即可。

如果前端页面没有CSRF_token,则一般会报错如下

HTTP Status 403 - Expected CSRF token not found. Has your session expired?

type Status report

message Expected CSRF token not found. Has your session expired?

description Access to the specified resource has been forbidden.

 

2.2.1 JSP页面

情况1:JSP表单域,可增加一个标签<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"> 

情况2:对于非表单域,增加<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" /> 

情况3:类似情况1

<form action="login"  method="post"> 
   <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}">   

</form>

情况4: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/Cubicluo/blog/859957

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值