CSRF简介——摘抄自《Spring实战(第4版)》

 我们可以回忆一下,当一个POST请求提交到“/spittles”上时,SpittleController将会为用户创建一个新的Spittle对象。但是,如果这个POST请求来源于其他站点的话,会怎么样呢?如果在其他站点提交如下表单,这个POST请求会造成什么样的结果呢?假设你禁不住获得一辆新汽车的诱惑,点击了按钮——那么你将会提交表单到如下地址http://www.spittr.com/spittles。如果你已经登录到了spittr.com,那么这就会广播一条消息,让每个人都知道你做了一件蠢事。这是跨站请求伪造(cross-site request forgery,CSRF)的一个简单样例。简单来讲,如果一个站点欺骗用户提交请求到其他服务器的话,就会发生CSRF攻击,这可能会带来消极的后果。尽管提交“I’m stupid!”这样的信息到微博站点算不上什么CSRF攻击的最糟糕场景,但是你可以很容易想到更为严重的攻击情景,它可能会对你的银行账号执行难以预期的操作。 

从Spring Security 3.2开始,默认就会启用CSRF防护。实际上,除非你采取行为处理CSRF防护或者将这个功能禁用,否则的话,在应用中提交表单时,你可能会遇到问题。

Spring Security通过一个同步token的方式来实现CSRF防护的功能。它将会拦截状态变化的请求(例如,非GET、HEAD、OPTIONS和TRACE的请求)并检查CSRF token。如果请求中不包含CSRF token的话,或者token不能与服务器端的token相匹配,请求将会失败,并抛出CsrfException异常。这意味着在你的应用中,所有的表单必须在一个“_csrf”域中提交token,而且这个token必须要与服务器端计算并存储的token一致,这样的话当表单提交的时候,才能进行匹配。

好消息是,Spring Security已经简化了将token放到请求的属性中这一任务。

   一、Freemarker模板集成Spring Security-CSRF防止功能

1.Spring Security配置防止CSRF为开启状态,默认情况下该功能是开启的,调用disable()方法可以禁止。

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* HTTP请求处理
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
String doUrl = "/**/*.do";
http
.formLogin().loginPage("/user/login.do")
.defaultSuccessUrl("/free/list.do")//启用FORM登录
.and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout","GET"))
.and().authorizeRequests().antMatchers("/user/login.do").permitAll()//登录页允许所有人访问
.and().portMapper().http(8898).mapsTo(8443) //添加端口映射,做测试用
.and().authorizeRequests().antMatchers(doUrl).authenticated()
.and().requiresChannel().antMatchers("/free/**",doUrl).requiresSecure()
.and().requiresChannel().antMatchers(doUrl).requiresInsecure()
.and().httpBasic();
//.and().csrf().disable(); //禁用CSRF
}

          2.Freemarker模板绑定_csrf 值

<#include "/templates/_base.ftl"/>
<@layout;section>
<#if section="title"> 用户登录
<#elseif section="css">
<#elseif section="content">
<div class="width:400px;height:300px;">
<h3>用户登录</h3>
<form name="f" action="/stest/user/login.do" method="POST">
<input name="${_csrf.parameterName}" type="hidden" value="${_csrf.token}">
<table>
<tbody>
<tr><td>User:</td><td><input type="text" name="username" value=""></td></tr>
<tr><td>Password:</td><td><input type="password" name="password"></td></tr>
<tr><td colspan="2"><input name="submit" type="submit" value="Login"></td></tr>
</tbody>
</table>
<p>${msg!}</p>
</form>
</div>
<#elseif section="scripts">
</#if>
</@layout>

疑问解析:属性_csrf是怎么产生的呢? 根据调试发现,这个属性是在org.springframework.security.web.csrf.CsrfFilter过滤器中赋值到request的属性集合中的。因此可以在视图绑定过程中,直接获取。源码截图如下

  3.查看登录页面输出的csrf-Token值,已经成功赋值。如果我们随便修改一下这个token值,然后post请求到服务端,会发现报403错误,请求被阻止。说明配置已经成功生效,防止了请求的伪造。

    

     

    

   二、当开启CSRF后,原来以Get方式,调用/logout,退出登录状态的功能失效了,跳转后报404错误。

 1、查看源码,发现框架方法里做了备注。大概意思就是开启CSRF后,logout方法需要以post方式提交。或者调用logoutRequestMatcher方法,显示设置/logout请求为GET方法

          

  2、用logoutRequestMatcher设置logout为get请求来解决404报错问题。POST方式比较简单这里就不在赘述。当然,实际项目中,最好选择以post方式退出系统。

http
.formLogin().loginPage("/user/login.do")
.defaultSuccessUrl("/free/list.do")//启用FORM登录
.and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout","GET"))

至此CSRF防止方案示例就讲完了。在项目中,对于post请求都需要注意提交_csrf到服务端。希望对你有所帮助,欢迎留言交流。

Spring-Security+Freemarker 开启跨域请求伪造防护功能的更多相关文章

  1. spring-security中的csrf防御机制(跨域请求伪造)

    什么是csrf? csrf又称跨域请求伪造,攻击方通过伪造用户请求访问受信任站点.CSRF这种攻击方式在2000年已经被国外的安全人员提出,但在国内,直到06年才开始被关注,08年,国内外的多个大型社 ...

  2. Django框架 之 跨域请求伪造

    Django框架 之 跨域请求伪造 浏览目录 同源策略与Jsonp 同源策略 Jsonp jQuery对JSONP的实现 CORS 简介 两种请求 同源策略与Jsonp 同源策略 同源策略(Same ...

  3. tornado下的跨站请求伪造(防护)

    跨站请求伪造(防护) 任何Web应用所面临的一个主要安全漏洞是跨站请求伪造,通常被简写为CSRF或XSRF,发音为"sea surf".这个漏洞利用了浏览器的一个允许恶意攻击者在受 ...

  4. Laravel 开启跨域请求

    项目中用到了接口,外部调用的时候老是请求不到,本地请求却没问题,查了下说是因为跨域的问题.根据网上所说解决方法如下: 1.建立中间件Cors.php命令:php artisan make:middle ...

  5. 关于CSRF跨域请求伪造的解决办法

    中秋节时候我们的应用在短信验证码这块被恶意刷单,比如被用来做垃圾短信之类的,如果大规模被刷也能造成不小的损失.这还只是短信验证码,如果重要的API遭到CSRF的攻击,损失不可估量.所以紧急加班解决了C ...

  6. Django-CSRF跨站请求伪造防护

    前言 CSRF全称Cross-site request forgery(跨站请求伪造),是一种网络的攻击方式,也被称为“One Click Attack”或者Session Riding,通常缩写为C ...

  7. spring boot跨域请求访问配置以及spring security中配置失效的原理解析

    一.同源策略 同源策略[same origin policy]是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源. 同源策略是浏览器安全的基石. 什么是源 源[orig ...

  8. CSRF(Cross Site Request Forgery, 跨站域请求伪造)

    CSRF(Cross Site Request Forgery, 跨站域请求伪造) CSRF 背景与介绍 CSRF(Cross Site Request Forgery, 跨站域请求伪造)是一种网络的 ...

  9. asp.net mvc 安全测试漏洞 "跨站点请求伪造" 问题解决

    IBM Security Appscan漏洞筛查-跨站请求伪造,该漏洞的产生,有多种情况: 1.WebApi的跨站请求伪造,需要对WebApi的请求头部做限制(此文不做详细介绍): 2.MVC Act ...

随机推荐

  1. Intellij 设置生成serialVersionUID的方法

  2. Django 初识

    Django  初识 一.前言 Django是一款网站架构,能够快速的搭建一个网站.openstack的界面显示使用的就是Django的框架.所以,学习openstack多少要了解一些Django的内 ...

  3. 配置python+mod_wsgi+apache 时 在浏览器中访问服务器时报错:Invalid HTTP_HOST header: 'XXXXX'. You may need to add u'XXXXX' to ALLOWED_HOSTS,在setting.py中添加‘*”无效的原因

    配置python+mod_wsgi+apache 时 在浏览器中访问服务器时报错:Invalid HTTP_HOST header: 'XXXXX'. You may need to add u'XX ...

  4. MySQL5.6安装(RPM)笔记

    1. 检查MySQL是否安装,如果有安装,则移除(rpm –e 名称)[root@localhost ~]# rpm -qa | grep -i mysqlmysql-libs-xxxxxxxxxx. ...

  5. 00_HTML入门第一天

    HTML入门 body标记的常见属性:bgcolor 设置背景颜色:text 设置文本颜色:link 设置链接颜色:vlink 设置已经访问了的链接颜色:alink 正在点击的链接颜色: meta是单 ...

  6. 树莓派用U盘安装系统

    * 需要使用Raspbian / Raspbian Lite或更高版本的2017-04-10版本 *不会SD卡装系统? 1.  先用装好Raspbian系统的SD卡启动 在命令行输入    echo ...

  7. 树莓派小车By 树莓派爱好者ITJoker(通过python socket通信实现树莓派视频小车)(一)

    本文由树莓派爱好者ITJoker 编辑,转载请注明出处.本人也有新浪博客同样是树莓派爱好者ITJoker 所需材料:树莓派2B或者2B以上,L2985n驱动板,若干排线,电池及电池盒,usb无线网卡( ...

  8. 布隆过滤器(BloomFilter)持久化

    摘要 Bloomfilter运行在一台机器的内存上,不方便持久化(机器down掉就什么都没啦),也不方便分布式程序的统一去重.我们可以将数据进行持久化,这样就克服了down机的问题,常见的持久化方法包 ...

  9. MP4大文件虚拟HLS分片技术,避免服务器大量文件碎片

    MP4大文件虚拟HLS分片技术,避免点播服务器的文件碎片 本文主要介绍了通过虚拟分片技术,把MP4文件,映射为HLS协议中的一个个小的TS分片文件,实现了在不实际切分MP4文件的情况下,通过HLS协议 ...

  10. 玩转spring boot——简单登录认证

    前言 在一个web项目中,某些页面是可以匿名访问的,但有些页面则不能.spring mvc提供了HandlerInterceptor接口来应对,只需要重写preHandle方法便可以实现此功能.那么使 ...