返回总目录


本篇目录

介绍###

CSRF【Cross-Site Request Forgery】跨站请求伪造是一种攻击类型,一般指的是一个恶意的网站、邮件、博客、即时消息、或程序使得用户的web浏览器对当前用户已认证的可信任网站执行一个自己不愿执行的操作。想要详细了解的可以查看百度CSRF,扩展阅读OWASP

这里简明描述一下如何在ASP.NET Web API中实现。

ABP框架尽可能地简化自动化了CSRF保护,现成的启动模板已经做了预配置。本文,会解释如何将它集成到ASP.NET平台的,以及它是如何工作的。

HTTP动词

无需对GET,HEAD,OPTIONS,TRACEHTTP动词做保护操作,因为正常情况下它们应该是无副作用的(不会更改数据库)。ABP只对POST,PUT,PATCH,DELETE动词实现了反伪造(Anti-Forgery)保护,可以使用本文中定义的特性来更改该行为。

ASP.NET MVC###

功能

大家都知道,ASP.NET MVC有自己内置的反伪造系统,但它有一些不足:

  • 需要为保护的所有actions添加ValidateAntiForgeryToken特性,这个容易忘记。
  • ValidateAntiForgeryToken特性只检查HTML 表单域中的__RequestVerificationToken,这就使得在AJAX请求中使用它非常困难或不可能,尤其是以"application/json"作为content-type发送请求时。在Ajax请求中,通常会在请求头中设置token。
  • 在JS代码中很难访问验证token,尤其是不在.cshtml文件中写JS。但我们需要在AJax请求中访问使用。
  • 即使可以在js中访问token,也需要为每个请求都在头部手动加入,很是麻烦。

ABP做了下面这些事情来客服上面的困难:

  • actions会被自动保护(通过AbpAntiForgeryMvcFilter)。自动保护可以应对大多数情况。当然,可以使用DisableAbpAntiForgeryTokenValidation特性为任何action和Controller关闭自动保护,也可以使用 ValidateAbpAntiForgeryToken特性打开。
  • 除了HTML的表单域,AbpAntiForgeryMvcFilter也会检查请求头中的token。因此,可以很容易对ajax请求使用反伪造token保护。
  • 在js中可以使用abp.security.antiForgery.getToken()函数获得token。
  • 为所有的ajax请求头部自动添加反伪造token。

集成

启动模板已经集成了现成的CSRF保护,如果需要手动将它添加到你的项目,那么请参照以下步骤。

Layout 视图

Layout视图中添加以下代码:

@{
SetAntiForgeryCookie();
}

这样,所有使用了这个布局页的页面都会包含这句代码了,该方法定义在ABP视图基类中,它会创建和设置正确的token cookie,使得在js端可以工作。如果有多个Layout的话,需要为每个布局添加上面的代码。

对于ASP.NET MVC 应用,只需要做这么多,所有的ajax请求都会自动工作。但是对于HTML 表单仍然需要使用** @Html.AntiForgeryToken()** HTML帮助方法,因为表单不是通过Ajax提交的,但是不需要在相应的action上使用ValidateAbpAntiForgeryToken 特性了。

配置

XSRF默认是打开的,也可以在模块的PreInitialize方法中关闭或配置,如下:

Configuration.Modules.AbpWeb().AntiForgery.IsEnabled = false;

也可以使用Configuration.Modules.AbpWebCommon().AntiForgery对象配置token和cookie名称。

ASP.NET WEB API###

功能

ASP.NET Web API不包括反伪造机制,ABP为ASP.NET Web API Controllers提供了基础设施来添加CSRF保护,并且是完全自动化的。

集成

ASP.NET MVC客户端

如果在MVC项目中使用了Web API,那么不需要额外的配置。只要Ajax请求是从一个配置的MVC应用中发出的,即使你的Web API层自宿主在其它进程中,也不需要配置。

其它客户端

如果你的客户端是其它类型的应用(比如,一个独立的angularjs应用,它不能像之前描述的那样使用SetAntiForgeryCookie()方法),那么你应该提供一种设置反伪造token cookie的方法。一种可能的实现方式是像下面那样创建一个api控制器:

using System.Net.Http;
using Abp.Web.Security.AntiForgery;
using Abp.WebApi.Controllers; namespace AngularForgeryDemo.Controllers
{
public class AntiForgeryController : AbpApiController
{
private readonly IAbpAntiForgeryManager _antiForgeryManager; public AntiForgeryController(IAbpAntiForgeryManager antiForgeryManager)
{
_antiForgeryManager = antiForgeryManager;
} public HttpResponseMessage GetTokenCookie()
{
var response = new HttpResponseMessage(); _antiForgeryManager.SetCookie(response.Headers); return response;
}
}
}

然后就可以从客户端调用这个action来设置cookie了。

ASP.NET Core###【以后补上】

客户端类库###

jQuery

abp.jquery.js中定义了一个ajax拦截器,它可以将反伪造请求token添加到每个请求的请求头中,它会从abp.security.antiForgery.getToken()函数中获得token。

Angularjs

Angularjs会将反伪造token自动添加到所有的ajax请求中,请点击链接查看Angularjs的XSRF保护一节。ABP默认使用了相同的cookie和header名称。因此,Angularjs集成是现成可用的。

其它类库

如果你使用了其它类库做Ajax请求,那么有三种选择:

Intercept XMLHttpRequest

因为所有的类库都使用了原生的js Ajax对象——XMLHttpRequest,因此可以定义一个简单的拦截器,将token添加到请求头部:

(function (send) {
XMLHttpRequest.prototype.send = function (data) {
this.setRequestHeader(abp.security.antiForgery.tokenHeaderName, abp.security.antiForgery.getToken());
return send.call(this, data);
};
})(XMLHttpRequest.prototype.send);

Use Library Interceptor

好的类库都会提供拦截点(比如 jquery和angularjs),因此,请查看文档学习如何拦截请求以及操作头部。

Add the Header Manually

最后,可以使用abp.security.antiForgery.getToken()获取token,然后手动为每个请求添加请求头,但是很可能不需要这么做,而是按照上面的方法解决问题。

内部原理###

你可能想知道ABP是如何处理这个的,实际上,ABP使用了和之前文档描述的angularjs机制是一样的。ABP会将token保存到一个cookie中,然后使用那个cookie设置请求头。这个实现也很好地集成到了ASP.NET MVC, Web API 和 Core框架。

ABP理论之CSRF的更多相关文章

  1. ABP理论之时间

    返回总目录 本篇目录 介绍 Clock 时区 绑定器和转换器 介绍 虽然有些应用针对的是一个特定的时区,但是也有一些应用针对多个不同的时区.为了满足这些需求,ABP为datetime操作提供了通用的基 ...

  2. 进军ABP第一天:ABP理论知识

    1.2.3 领域层领域层就是业务层,是一个项目的核心,所有业务规则都应该在领域层实现. ( 实体(Entity ) 实体代表业务领域的数据和操作,在实践中,通过用来映射成数据库表. ( 仓储(Repo ...

  3. 实战框架ABP

    abp及实战框架概述 接触abp也快一年了,有过大半年的abp项目开发经验,目前项目中所用的abp框架版本为0.10.3,最新的abp框架已经到了1.4,并且支持了asp.net core.关于abp ...

  4. ABP框架理论研究总结(典藏版)

    目前,我已经完成了Module-Zero的翻译,请查看我的<Module-Zero学习目录>. 到现在为止,使用ABP框架开发正式项目已经3个月有余了,期间翻阅了大量文档资料,包括ABP官 ...

  5. C#高级知识点&(ABP框架理论学习高级篇)——白金版

    前言摘要 很早以前就有要写ABP高级系列教程的计划了,但是迟迟到现在这个高级理论系列才和大家见面.其实这篇博客很早就着手写了,只是楼主一直写写停停.看看下图,就知道这篇博客的生产日期了,谁知它的出厂日 ...

  6. ABP框架实践基础篇之开发UI层

    返回总目录<一步一步使用ABP框架搭建正式项目系列教程> 说明 其实最开始写的,就是这个ABP框架实践基础篇.在写这篇博客之前,又回头复习了一下ABP框架的理论,如果你还没学习,请查看AB ...

  7. ABP框架搭建项目系列教程基础版完结篇

    返回总目录<一步一步使用ABP框架搭建正式项目系列教程> 经过前面十二篇的基础教程,现在终于该做个总结了. 回顾 第一篇,我们建议新手朋友们先通过ABP官网的启动模板生成解决方案,因为这样 ...

  8. Abp(.NetCore)开发与发布过程2

    在Abp(.NetCore)开发过程中遇到很多问题,今天记录下Abp的防CSRF功能(AntiForgeryToken ), 背景知识. AntiForgeryToken 可以说是处理/预防CSRF的 ...

  9. 万水千山ABP - 时区问题

    关于时间和时区问题,后面的参考文章中有详细的描述. 我遇到的问题是: 在MVC视图页面中,显示记录的生成时间 CreationTime <div> @Model.CreationTime ...

随机推荐

  1. Summary of Critical and Exploitable iOS Vulnerabilities in 2016

    Summary of Critical and Exploitable iOS Vulnerabilities in 2016 Author:Min (Spark) Zheng, Cererdlong ...

  2. DDD 领域驱动设计-看我如何应对业务需求变化,愚蠢的应对?

    写在前面 阅读目录: 具体业务场景 业务需求变化 "愚蠢"的应对 消息列表实现 消息详情页实现 消息发送.回复.销毁等实现 回到原点的一些思考 业务需求变化,领域模型变化了吗? 对 ...

  3. JavaScript Object对象

    目录 1. 介绍:阐述 Object 对象. 2. 构造函数:介绍 Object 对象的构造函数. 3. 实例属性:介绍 Object 对象的实例属性:prototype.constructor等等. ...

  4. CRL快速开发框架系列教程十二(MongoDB支持)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  5. JS继承之寄生类继承

    原型式继承 其原理就是借助原型,可以基于已有的对象创建新对象.节省了创建自定义类型这一步(虽然觉得这样没什么意义). 模型 function object(o){ function W(){ } W. ...

  6. 记录一则Linux SSH的互信配置过程

    需求:四台Linux主机,IP地址为192.168.10.10/11/12/13,配置登录用户的互信 1.各节点ssh-keygen生成RSA密钥和公钥 ssh-keygen -q -t rsa -N ...

  7. 介绍一款原创的四则运算算式生成器:CalculateIt2

    家里小朋友读一年级了,最近每天都有一些10以内的加减法口算练习,作为程序员爸爸,自然也是想办法能够偷懒,让电脑出题,给小朋友做些练习.于是,自己在业余时间开发了一个四则运算算式生成器,名为:Calcu ...

  8. nodejs操作arduino入门(javascript操作底层硬件)

    用Javascript来操作硬件早就不是一件稀奇的事情了. 所以作为一名电子专业出身的FE,我也打算尝试一下用js来驱动arduino: 要想操作这些底层硬件,肯定是需要一些工具的,我这里介绍的工具主 ...

  9. C++整数转字符串的一种方法

    #include <sstream> //ostringstream, ostringstream::str() ostringstream stream; stream << ...

  10. iOS之绘制虚线

    /*   ** lineFrame:     虚线的 frame   ** length:        虚线中短线的宽度   ** spacing:       虚线中短线之间的间距   ** co ...