当前位置:首页 > 编程教程 > java技术文章 > 详解利用spring-security解决CSRF问题

解析利用spring-security解决CSRF问题

  • 发布时间:
  • 作者:码农之家
  • 点击:196

这篇文章主要知识点是关于spring、security、CSRF、的内容,如果大家想对相关知识点有系统深入的学习,可以参阅以下电子书

Java Web从入门到精通
  • 类型:java web开发大小:156.8 MB格式:PDF作者:明日科技
立即下载

Tags:Spring security CSRF 

详解利用spring-security解决CSRF问题

CSRF介绍

CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。

具体SCRF的介绍和攻击方式请参看百度百科的介绍和一位大牛的分析:
CSRF百度百科
浅谈CSRF攻击方式

配置步骤

1.依赖jar包

<properties> 
    <spring.security.version>4.2.2.RELEASE</spring.security.version> 
  </properties> 
<dependency> 
        <groupId>org.springframework.security</groupId> 
        <artifactId>spring-security-core</artifactId> 
        <version>${spring.security.version}</version> 
      </dependency> 
 
      <dependency> 
        <groupId>org.springframework.security</groupId> 
        <artifactId>spring-security-web</artifactId> 
        <version>${spring.security.version}</version> 
      </dependency> 
 
      <dependency> 
        <groupId>org.springframework.security</groupId> 
        <artifactId>spring-security-config</artifactId> 
        <version>${spring.security.version}</version> 
      </dependency> 

2.web.xml配置

<filter> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
  </filter> 
 
  <filter-mapping> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <url-pattern>/*</url-pattern> 
  </filter-mapping> 

3.Spring配置文件配置

<bean id="csrfSecurityRequestMatcher" class="com.xxx.CsrfSecurityRequestMatcher"></bean> 
 
  <security:http auto-config="true" use-expressions="true"> 
    <security:headers> 
      <security:frame-options disabled="true"/> 
    </security:headers> 
    <security:csrf request-matcher-ref="csrfSecurityRequestMatcher" /> 
  </security:http> 

4.自定义RequestMatcher的实现类CsrfSecurityRequestMatcher

这个类被用来自定义哪些请求是不需要进行拦截过滤的。如果配置csrf,所有http请求都被会CsrfFilter拦截,而CsrfFilter中有一个私有类DefaultRequiresCsrfMatcher。

源码1:DefaultRequiresCsrfMatcher类

private static final class DefaultRequiresCsrfMatcher implements RequestMatcher { 
    private final HashSet<String> allowedMethods; 
 
    private DefaultRequiresCsrfMatcher() { 
      this.allowedMethods = new HashSet(Arrays.asList(new String[]{"GET", "HEAD", "TRACE", "OPTIONS"})); 
    } 
 
    public boolean matches(HttpServletRequest request) { 
      return !this.allowedMethods.contains(request.getMethod()); 
    } 
  } 

从这段源码可以发现,POST方法被排除在外了,也就是说只有GET|HEAD|TRACE|OPTIONS这4类方法会被放行,其它Method的http请求,都要验证_csrf的token是否正确,而通常post方式调用rest接口服务时,又没有_csrf的token,所以会导致我们的rest接口调用失败,我们需要自定义一个类对该类型接口进行放行。来看下我们自定义的过滤器:

源码2:csrfSecurityRequestMatcher类

public class CsrfSecurityRequestMatcher implements RequestMatcher { 
  private Pattern allowedMethods = Pattern.compile("^(GET|HEAD|TRACE|OPTIONS)$"); 
  private RegexRequestMatcher unprotectedMatcher = new RegexRequestMatcher("^/rest/.*", null); 
 
  @Override 
  public boolean matches(HttpServletRequest request) { 
    if(allowedMethods.matcher(request.getMethod()).matches()){ 
      return false; 
    } 
 
    return !unprotectedMatcher.matches(request); 
  } 
} 

说明:一般我们定义的rest接口服务,都带上 /rest/ ,所以如果你的项目中不是使用的这种,或者项目中没有rest服务,这个类完全可以省略的。

5.post请求配置

一般我们的项目中都有一个通用的jsp文件,就是每个页面都会引用的,所以我们可以在通用文件中做如下配置:

<meta name="_csrf" content="${_csrf.token}"/> 
<meta name="_csrf_header" content="${_csrf.headerName}"/> 
 
<script> 
 
  var token = $("meta[name='_csrf']").attr("content"); 
  var header = $("meta[name='_csrf_header']").attr("content"); 
  $.ajaxSetup({ 
    beforeSend: function (xhr) { 
      if(header && token ){ 
        xhr.setRequestHeader(header, token); 
      } 
    }} 
  ); 
</script> 

$.ajaxSetup的意思就是给我们所有的请求都加上这个header和token,或者放到form表单中。注意,_csrf这个要与spring security的配置文件中的配置相匹配,默认为_csrf。

源码解析

我们知道,既然配置了csrf,所有的http请求都会被CsrfFilter拦截到,所以看下CsrfFilter的源码就对原理一目了然了。这里我们只看具体过滤的方法即可:

源码3:CsrfFilter的doFilterInternal方法

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { 
    request.setAttribute(HttpServletResponse.class.getName(), response); 
    CsrfToken csrfToken = this.tokenRepository.loadToken(request); 
    boolean missingToken = csrfToken == null; 
    if(missingToken) {//如果token为空,说明第一次访问,生成一个token对象 
      csrfToken = this.tokenRepository.generateToken(request); 
      this.tokenRepository.saveToken(csrfToken, request, response); 
    } 
 
    request.setAttribute(CsrfToken.class.getName(), csrfToken); 
    //把token对象放到request中,注意这里key是csrfToken.getParameterName()= _csrf,所以我们页面上才那么写死。 
    request.setAttribute(csrfToken.getParameterName(), csrfToken); 
     
    //这个macher就是我们在Spring配置文件中自定义的过滤器,也就是GET,HEAD, TRACE, OPTIONS和我们的rest都不处理 
    if(!this.requireCsrfProtectionMatcher.matches(request)) { 
      filterChain.doFilter(request, response); 
    } else { 
      String actualToken = request.getHeader(csrfToken.getHeaderName()); 
      if(actualToken == null) { 
        actualToken = request.getParameter(csrfToken.getParameterName()); 
      } 
 
      if(!csrfToken.getToken().equals(actualToken)) { 
        if(this.logger.isDebugEnabled()) { 
          this.logger.debug("Invalid CSRF token found for " + UrlUtils.buildFullRequestUrl(request)); 
        } 
 
        if(missingToken) { 
          this.accessDeniedHandler.handle(request, response, new MissingCsrfTokenException(actualToken)); 
        } else { 
          this.accessDeniedHandler.handle(request, response, new InvalidCsrfTokenException(csrfToken, actualToken)); 
        } 
 
      } else { 
        filterChain.doFilter(request, response); 
      } 
    } 
  } 

从源码中可以看到,通过我们自定义的过滤器以外的post请求都需要进行token验证。

本来呢,是想截图弄个案例上去的,然后通过断点看看页面和后台的传值情况....不过,我这里没法上传图片抓狂。好吧,就总结这么多吧!如果有写的不对的或者有其他问题可以留言交流。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持码农之家。

以上就是本次给大家分享的关于java的全部知识点内容总结,大家还可以在下方相关文章里找到相关文章进一步学习,感谢大家的阅读和支持。

Java 相关电子书
学习笔记
网友NO.419135

使用SpringSecurity处理CSRF攻击的方法步骤

CSRF漏洞现状 CSRF(Cross-site request forgery)跨站请求伪造,也被称为One Click Attack或者Session Riding,通常缩写为CSRF或XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装成受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。 CSRF是一种依赖web浏览器的、被混淆过的代理人攻击(deputy attack)。 POM依赖 !-- 模板引擎 freemarker --dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-freemarker/artifactId/dependency!-- Security (只使用CSRF部分) --dependency groupIdorg.springframework.security/groupId artifactIdspring-security-web/artifactId/dependency 配置过滤器 @SpringBootApplicationpublic class Application { public static……

网友NO.979808

spring security CSRF防护的示例代码

CSRF是指跨站请求伪造(Cross-site request forgery),是web常见的攻击之一。 从Spring Security 4.0开始,默认情况下会启用CSRF保护,以防止CSRF攻击应用程序,Spring Security CSRF会针对PATCH,POST,PUT和DELETE方法进行防护。 我这边是spring boot项目,在启用了@EnableWebSecurity注解后,csrf保护就自动生效了。 所以在默认配置下,即便已经登录了,页面中发起PATCH,POST,PUT和DELETE请求依然会被拒绝,并返回403,需要在请求接口的时候加入csrfToken才行。 如果你使用了freemarker之类的模板引擎或者jsp,针对表单提交,可以在表单中增加如下隐藏域: input type = “hidden” name = “${_csrf.parameterName}” value = “${_csrf.token}” / 如果您使用的是JSON,则无法在HTTP参数中提交CSRF令牌。相反,您可以在HTTP头中提交令牌。一个典型的模式是将CSRF令牌包含在元标记中。下面显示了一个JSP示例:……

网友NO.225247

详解如何在spring boot中使用spring security防止CSRF攻击

CSRF是什么? CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。 CSRF可以做什么? 你这可以这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账......造成的问题包括:个人隐私泄露以及财产安全。 CSRF漏洞现状 CSRF这种攻击方式在2000年已经被国外的安全人员提出,但在国内,直到06年才开始被关注,08年,国内外的多个大型社区和交互网站分别爆出CSRF漏洞,如:NYTimes.com(纽约时报)、Metafilter(一个大型的BLOG网站),YouTube和百度HI......而现在,互联网上的许多站点仍对此毫无防备,以至于安全业界称CSRF为“沉睡的巨人”。 在一个spring boot项目中,需要防止CSRF攻击,可以只把……

<
1
>

电子书 编程教程 PC软件下载 安卓软件下载

Copyright 2018-2020 xz577.com 码农之家

本站所有电子书资源不再提供下载地址,只分享来路

免责声明:网站所有作品均由会员网上搜集共同更新,仅供读者预览及学习交流使用,下载后请24小时内删除

版权投诉 / 书籍推广 / 赞助:QQ:520161757