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. javascript对象的标签

    [[proto]]标签 [[class]]标签 [[class]] 标签,代表这对象是哪个类型的.在js中不能直接访问到.可以通过Object.prototype.toString.call(obj) ...

  2. 【Code clone】Distributed Code Clone Detection Based on Index

    1 摘要  随着软件产业的发展,代码克隆现象越来越常见,随之带来的安全漏洞.可维护性.产权等问题也引起人们重视.代码克隆按照复制程度分为4类:完全复制.修改名称.更换顺序和自实现.现有的代码克隆检测工 ...

  3. 05_Javascript进阶第一天

    内部私有函数 function a(){ alert('aaa'); return function b(){ alert('bbb'); } } //调用内部私有函数b,方法1 var func=a ...

  4. TP手册学习第一天

    调试执行的sql语句 User::get(1); echo User::getLastSql(); 方法直接返回当前的查询SQL而不执行fetchSql echo User::fetchSql()-& ...

  5. 【转】VMware 克隆 Linux 系统后找不到 eth0 网卡问题

    [问题描述] 使用 VMware 虚拟机的克隆功能,快速复制已安装好的 Linux 系统. 克隆完成之后,发现没有 eth0 网卡. [解决方法] 1. 编辑 /etc/udev/rules.d/70 ...

  6. Linux系统中常用操作命令

    常用指令 ls        显示文件或目录     -l          列出文件详细信息l(list)     -a         列出当前目录下所有文件及目录,包括隐藏的a(all)mkdi ...

  7. python 字符串操作方法详解

    字符串序列用于表示和存储文本,python中字符串是不可变对象.字符串是一个有序的字符的集合,用于存储和表示基本的文本信息,一对单,双或三引号中间包含的内容称之为字符串.其中三引号可以由多行组成,编写 ...

  8. 深入浅出Hadoop之HDFS

    hadoop生态系统一直是大数据灵域的热点,其中包括今天要聊的HDFS,和计划以后想聊的yarn, mapreduce, spark, hive, hbase, 已经聊过的zookeeper,等等. ...

  9. VS下WPF自定义控件的基本步骤和基本代码实现

    一.自定义控件的基本步骤: (本示例项目名称为:W:添加的自定义控件名称为) 1.  在"解决方案资源管理器"窗口的项目名上: 右击à添加à新建项(Ctrl+Shift+A) 2. ...

  10. nongsanli

    之后的内容只能追加,不可以修改,删除. 1.    mysql可以对字段进行MD5加密, 加密插入:INSERT INTO t_user(id,username,PASSWORD) VALUES('5 ...