接触Asp.net boilerplate 一段时间,一次同事将他的代码添加到zero项目模板中,他将路由配置成他的页面,目的是要让zero项目登录成功之后跳转到他的页面,可是通过fiddler监视请求报了一个错误

后来得知CSRF,翻阅下ABP Documents,了解下

  介绍

(CSRF)跨站点请求伪造 是一种恶意攻击,一个恶意网站,电子邮件,博客,或者应用程序导致一个已认证的用户在受信任的站点上执行一个不安全的操作(OWASP).

这里也简要的介绍了它在ASP.NET WEBAPI下如何实现

ABP架构尽可能多的去简化和自动化的完成CSRF防护,启动模板自带预定义配置和开箱即用,在本文中,我们将解释它是如何集成到ASP.NET平台并且了解它是如何工作的。

  HTTP动词

通常情况下,我们不需要保护GET,HEAD,OPTIONS和TRACE 这些HTTP操作,因为他们不会改变数据库,然而ABP假设(仅仅对POST,PUT,PATCH和DELETE这些HTTP动词进行保护),您也可以通过在文档中被定义的特性更改这一行为

ASP.NET MVC

特征

  正如你了解的那样,ASP.NET有它自己内置的防护系统,但是它有一些不足

  >在被保护的所有的ACTION上必须添加 ValidateAntiForgeryToken 注解,这样我们可能忘记在这些方法上添加此注解。

  >ValidateAntiForgeryToken 注解仅是检查表单的 _RequestVerificationToken 字段,这使得很难或者是不可能使用AJAX请求,尤其是如果你发送的请求的Content-Type 为 application/json,在AJAX中这通常是很常见的请求头。

  >这样在javascript代码中很难访问验证token(特别是如果你在.cshtml文件中不写javascript代码),在我们的AJAX请求中需要访问它

  >尽管我们用javascript可以访问到token,但是我们要为每次请求手动添加请求报文头

ABP做了以下的事情以应对这些困难

  >无需为POST,PUT,PATCH,DELETE添加 ValidateAniForgeryToken 注解,因为它们是自动的被保护(通过 AbpAntiForgeryMvcFilter),大多数情况下 自动保护 已经足够了,反之你也可以通过 DisableAbpAntiForgeryTokenValidation 注解 去禁用一个Action或者一个Controller,你也可以通过 ValidateAbpAntiForgeryToken 注解去启用一个Action或者一个Controller。

  > AbpAntiForgeryMvcFilter 除了表单字段之外还会检查请求头中的token,因此我们可以很容易的在AJAX请求中使用请求伪造保护。

  >提供了 abp.security.antiForgery.getToken()方法用javascript获取token ,甚至你不需要使用它。

  >为所有的AJAX请求头中自动的添加anti forgery token

因此,他几乎无缝协作。

整合

项目启动模板已经集成了开箱即用的CSRF防护,如果你要手动将它添加到你的项目中(也许你想要在创建项目之前添加它),下边将提供向导

模板视图

我们应该将以下代码添加到模板视图中

@{
SetAntiForgeryCookie();
}

因此,所有的页面使用这个布局页都将包含它,这个方法定义在视图基类中, 它创建并设置合适的cookie token ,用于工作中的javascript,如果你有多个布局页,添加它到所有页面。

这些就是我们应该为ASP.NET MVC所做的,所有的AJAX请求会自动工作,但是我们还是应该为不被配置的html表单使用 @Html.AntiForgeryToken() HTML帮助方法(但是不需要在对应的方法添加 ValidateAbpAntiForgeryToken 注解)

配置

XSRF保护默认启用,你也可以在你的模块的预初始化方法中禁用它  ,例如:

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

你还可以使用 Configuration.Modules.AbpWebCommon().AntiForgery 配置token和cookie的名字。

ASP.NET WEB API

特征

ASP.NET WEB API并不包含防伪造机制,Asp.net boilerplate 为ASP.NET提供了CSRF 防护的基础设施,以增加对ASP.NET WEBAPI完全自动化的CSRF保护。

集成

在 ASP.NET 客户端中

如何你在一个MVC项目中使用Web Api,无需增加额外的配置,甚至你在另外的进程中自托管你的Web Api 层,只要你从一个配置过的MVC应用程序中发送的AJAX请求,就无需配置。

在其他的客户端中

如何你的客户端是不同种类的应用程序(比如说,正如前面描述的单页面Angularjs应用程序,将不能使用 SetAntiForgeryCookie() 方法),这是应该提供一种设置anti frogery 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;
}
}
}

然后你就可以在客户端调用这个方法去设置Cookie。

ASP.NET Core

ASP.NET Core 相比前一版本(ASP.NET MVC 5.x的)有更好的防伪造机制:

  >它有 AutoValidateAntiforgeryTokenAttribute 类,对所有的POST,PUT,PATCH和 DELETE操作有自动的防伪造验证。

  >存在 ValidateAntiForgeryToken 和IgnoreAntiforgeryToken 来控制token验证。

  >如果没有明确的禁用它,将自动添加token到你的表单中,所以大多数情况下不需要调用 @Html.AntiForgeryToken() 方法。

  >它可以在请求报文头和表单字段读取token。

ABP增加了以下功能:

  >自动的为所有AJAX请求添加防伪造token 。

  >还在javascript中提供了 abp.security.antiForgery.getToken()方法来得到token ,尽管你不需要它。

集成

启动模板已经集成了开箱即用的CSRF防护,如果您需要手动添加到您的项目中(也许你的项目在我们添加它之前创建),请参照指南。

启动类

首先,我们应该在启动类 ConfigureServices 中加入MVC的同时 并将 AutoValidateAntiforgeryTokenAttribute 添加到全局过滤器 :

 services.AddMvc(options =>
{
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});

这样,所有的MVC 动作(除了GET,HEAD,OPTIONS和TRACE正如之前的那些)都会自动验证token 。

布局视图

我们应该在布局视图上添加以下代码:

@using Abp.Web.Security.AntiForgery
@inject IAbpAntiForgeryManager AbpAntiForgeryManager
@{
AbpAntiForgeryManager.SetCookie(Context);
}

因此所有的页面使用布局页也将包含它,同样这个方法也是ABP视图基类中定义的,它创建并设置合适的token cookie,在javascript端工作,如果你有多个布局页面,同样将这些添加到这些页面上。

这些就是我们应该为ASP.NET CORE 所做的所有的AJAX请求都会自动的执行,而对于非AJAX 的表单提交,如果你在表单中使用Asp-*的标签,ASP.NET CORE 会自动的为表单添加防伪造token,所以正常情况下不需要使用 @Html.AntiForgeryToken() 方法。

客户端库

正如我们之前声明的那样,防伪造token应该在所有的AJAX请求头中被加入,我们将看到他是如何完成的。

jQuery

abp.jquery.js 为每一个添加token的请求定义了一个拦截器,从这个 abp.security.antiForgery.getToken()  javascript 方法中获取token。

Angularjs

Angularjs 会自动添加防伪造token到所有的AJAX请求,详见Angualrjs 文档 :跨站请求伪造(XSRF)保护。ABP默认使用相同的cookie和头文件名。因此,Angularjs 整合工作开箱即用。

其他库

如何你为AJAX 请求使用任何其他的库,你有三种选择:

拦截XMLHttpRequest

由于所有的库使用javascript 的本地 AJAX对象,XMLHttpRequest ,你可以像这个例子一样去定义简单的拦截器并添加token到header中:

 (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);

使用库拦截器

一个好的库应该提供拦截点(像jQuery和Angularjs)。所以应该按照你供应商的文档并了解如何拦截请求和操作报文头。

手动添加报文头

最后的操作,你也可以通过使用abp.security.antiForgery.getToken() 方法来 获得token并且可以手动添加到请求头中。但是你可能并不需要这么做,可以通过前面描述的那样解决问题。

本质

你可能想了解ABP如何处理它。事实上,我们使用之前提到的Angualrjs文档提到相同的机制。ABP在cookie中存储token(如上所述),并设置请求头,这也很好的与ASP.NET MVC ,ASP.NET WEB API,CORE FRAMEWORK结合在一起进行验证。

 

step_by_step_CSRF/ XSRF_问题描述的更多相关文章

  1. [内核笔记1]内核文件结构与缓存——inode和对应描述

    由来:公司内部外网记录日志的方式现在都是通过Nginx模块收到数据发送到系统消息队列,然后由另外一个进程来从消息队列读取然后写回磁盘这样的操作,尽量的减少Nginx的阻塞. 但是由于System/V消 ...

  2. PhpStorm和WAMP配置调试参数,问题描述Error. Interpreter is not specified or invalid. Press “Fix” to edit your project configuration.

    PhpStorm和WAMP配置调试参数 问题描述: Error. Interpreter is not specified or invalid. Press “Fix” to edit your p ...

  3. 杂项之python描述符协议

    杂项之python描述符协议 本节内容 由来 描述符协议概念 类的静态方法及类方法实现原理 类作为装饰器使用 1. 由来 闲来无事去看了看django中的内置分页方法,发现里面用到了类作为装饰器来使用 ...

  4. ASP.NET MVC 描述类型(二)

    ASP.NET MVC 描述类型(二) 前言 上个篇幅中说到ControllerDescriptor类型的由来过程,对于ControllerDescriptor类型来言ActionDescriptor ...

  5. ASP.NET MVC 描述类型(一)

    ASP.NET MVC 描述类型(一) 前言 在前面的好多篇幅中都有提到过ControllerDescriptor类型,并且在ASP.NET MVC 过滤器(一)篇幅中简单的描述过,今天我们就来讲一下 ...

  6. python描述符理解

    Python中的描述符是一个相对底层的概念 descriptor Any object which defines the methods get(), set(), or delete(). Whe ...

  7. 网站实现微信登录之回调函数中登录逻辑的处理--基于yii2开发的描述

    上一篇文章网站实现微信登录之嵌入二维码中描述了如何在自己的登录页面内嵌入登录二维码,今天的这篇文章主要是描述下在扫码成功之后微信重定向回网站后登录逻辑的处理,其实也就是验证身份信息,授权用户登录的逻辑 ...

  8. 网站实现微信登录之嵌入二维码——基于yii2开发的描述

    之前写了一篇yii2获取登录前的页面url地址的文章,然后发现自己对于网站实现微信扫码登录功能的实现不是很熟悉,所以,我会写2-3篇的文章来描述下一个站点如何实现微信扫码登录的功能,来复习下微信扫码登 ...

  9. 深入学习jQuery描述文本内容的3个方法

    × 目录 [1]html() [2]text() [3]val()[4]总结 前面的话 在javascript中,描述元素内容有5个属性,分别是innerHTML.outerHTML.innerTex ...

随机推荐

  1. JS语法基础

    js声明 <!--在head标签中使用script标签进行js代码域声明--> <script type="text/javascript" language=& ...

  2. C# 6.0:Expression – Bodied Methods

    Expression-bodied 方法是C# 6.0 中另一个能简化代码的特性.我们已经对lambda表达式将funciton和delegation关联起来的这种用法很熟悉了.Expression- ...

  3. linux中.nfsxxxx引起的文件无法删除

    一个linux系统中的某个文件夹无法删除,使用ls -al查看有1个.nfsxxxx的文件无法删除. 使用lsof +D /filepath/,查看到文件被一个进程一直占用. 再使用ps -aux | ...

  4. java-消息中间件-基于内存的mq

    如果用户的请求比较费时,可以考虑将用户的请求信息放到队列中,立即返回给用户处理中等信息,这样可以给用户比较流畅的体验,后端可以利用单独的服务消费消息,做到了解耦,提高了并发能力. 本文使用jdk为我们 ...

  5. 【转】Python 之 元类

    原文链接: https://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python      http://python.jo ...

  6. spring boot profiles 实现多环境下配置切换 docker版

    1,前言 开发环境总需要调试,docker直接部署不需要调试,环境配置不一样,这里的目的只是,在docker文件环境与开发环境使用不同的配置文件,项目结构如下 2,设置项目配置文件 默认配置文件 ap ...

  7. 给查询出的SQL记录添加序号列,解决方法有以下两种

    第一: select ROW_NUMBER() OVER (ORDER BY a.字段 ASC) AS XUHAO,a.* from table a (table 为表名,字段为表a中的字段名) 第二 ...

  8. javascript websocket 心跳检测机制介绍

    ====测试代码: ==index.html <!DOCTYPE html> <html lang="en"> <head> <meta ...

  9. 自动化接口测试(java)

    githup地址:https://github.com/SailFan/autoTestMock 包结构: common包 ExtentTestNGIReporterListener.java 为测试 ...

  10. IE8图片上传预览

    $("#smallImg").attr('style', "filter:progid:DXImageTransform.Microsoft.AlphaImageLoad ...