首页 > 代码库 > Abp(.NetCore)开发与发布过程2

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

在Abp(.NetCore)开发过程中遇到很多问题,今天记录下Abp的防CSRF功能(AntiForgeryToken ),


背景知识。

AntiForgeryToken 可以说是处理/预防CSRF的一种处理方案。

那么什么是CSRF?

CSRF(Cross-site request forgery)是跨站请求伪造,也被称为One Click Attack或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。

简单理解的话就是:有人盗用了你的身份,并且用你的名义发送恶意请求

最近几年,CSRF处于不温不火的地位,但是还是要对这个小心防范!


 

  ABP默认开启了防CSRF的功能,具体参见 Startup 类,

技术分享

但后来发现,即使在表单中不添加@Html.AntiForgeryToken() 也可以请求成功,例如

  1.$.ajax 在 使用 jQuery.ajax 时不用设置 @Html.AntiForgeryToken()

  注意 在请求Controller的POST方法时,需要使 contentType = ‘application/x-www-form-urlencoded‘,这应该是.NetCore的奇怪特性。如果contentType = ‘application/json’,那么在Controller的方法中应该设置[FormBody]

  如果不这么做,后台是接收不到值的。

  技术分享

  2.abp.ajax()方法,abp.ajax以一个对象作为接收选项。你可以传递任何在jQuery的$.ajax方法中的参数。 默认值:dataType:‘json’,type:‘POST’,contentType:‘application/json’,

  技术分享

  在 使用 abp.ajax 时也可以不用设置 @Html.AntiForgeryToken()

 

这是为什么呢? 原来abp.js在我们请求时自动为我们的请求头添加了RequestVerificationToken,其名称为 “X-XSRF-TOKEN”

技术分享

查看ABP的源码,在AbpAntiForgeryConfiguration中设置了定义了TokenCookieName和TokenHeaderName。一个是token保存在Cookie中时的名字,一个是token在请求头中被传输的名字

技术分享

 并且在AbpAspNetCoreModule中自定义了RequestVerificationToken的名字为“X-XSRF-TOKEN”。(这是微软定义的另一种验证方式,即不从表单中传输和获取token值,而是从请求头中获取。默认的名字是“RequestVerificationToken”当然你也可以自定义它。)

技术分享

当然 token值的获取在AbpAspNetCoreAntiForgeryManager中,源码如下。

技术分享

然后给IAbpAntiForgeryManager添加了一个扩展方法:SetCookie 

 技术分享

最终,在我们的 Account/_Layout.cshtml 和 Shared\_Layout.cshtml 中调用此方法:

技术分享

这也是为什么在项目测试阶段,如果跳过Account/_Layout.cshtml 和 Shared\_Layout.cshtml 步骤之后的请求都不会成功(只报400错误)的原因。

 

那为什么用abp.ajax 或者 $.ajax时不用设置 @Html.AntiForgeryToken()呢?

  接下来来看看abp.js

技术分享

在 abp.jquery.js中,

技术分享

技术分享

ajaxSend() 方法在 AJAX 请求开始时执行函数。它是一个 Ajax 事件。也就是说 在每个ajax请求前,abp为我们的请求头上加上了“X-XSRF-TOKEN”。

 

这就是一整套ABP的AntiForgeryToken获取和验证体系。

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