接觸Asp.net boilerplate 一段時間,一次同事將他的代碼添加到zero項目模板中,他將路由配置成他的頁面,目的是要讓zero項目登錄成功之後跳轉到他的頁面,可是通過fiddler監視請求報了一個錯誤 後來得知CSRF,翻閱下ABP Documents,瞭解下 介紹 (CSRF)跨站點 ...
接觸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保護預設啟用,你也可以在你的模塊的預初始化方法中禁用它 ,例如:
1 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 添加到全局過濾器 :
1 services.AddMvc(options => 2 { 3 options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()); 4 });
這樣,所有的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中:
1 (function (send) { 2 XMLHttpRequest.prototype.send = function (data) { 3 this.setRequestHeader(abp.security.antiForgery.tokenHeaderName, abp.security.antiForgery.getToken()); 4 return send.call(this, data); 5 }; 6 })(XMLHttpRequest.prototype.send);
使用庫攔截器
一個好的庫應該提供攔截點(像jQuery和Angularjs)。所以應該按照你供應商的文檔並瞭解如何攔截請求和操作報文頭。
手動添加報文頭
最後的操作,你也可以通過使用abp.security.antiForgery.getToken() 方法來 獲得token並且可以手動添加到請求頭中。但是你可能並不需要這麼做,可以通過前面描述的那樣解決問題。
本質
你可能想瞭解ABP如何處理它。事實上,我們使用之前提到的Angualrjs文檔提到相同的機制。ABP在cookie中存儲token(如上所述),並設置請求頭,這也很好的與ASP.NET MVC ,ASP.NET WEB API,CORE FRAMEWORK結合在一起進行驗證。