ASP.NET Core 中的Ajax全局Antiforgery Token配置


前言

本文基於官方文檔 《在 ASP.NET Core 防止跨站點請求偽造 (XSRF/CSRF) 攻擊》擴展另一種全局配置Antiforgery方法,適用於使用ASP.NET Core Razor + JQuery Ajax的項目,喜歡玩前后端分離的同學可以酌情參考,但希望不要對XSRF/CSRF掉以輕心,更不要不做處理。

Antiforgery Token 介紹

跨站點請求偽造(XSRF/CSRF)攻擊跟瀏覽器中登錄驗證之后保存的Cookie有關,惡意站點通過向攻擊目標站點發起非法請求時,瀏覽器按規則是會帶上Cookie信息的,此時被攻擊站點就會認為是用戶操作行為,如果被利用在修改密碼等操作上,對用戶的信息安全就會帶來威脅。為抵御 CSRF 攻擊最常用的方法是使用同步器標記模式(STP)。 而Antiforgery Token(防偽令牌)是ASP.NET Core中的STP實現方案。

STP的防御過程:

  1. 服務器發送到客戶端的當前用戶的標識相關聯的令牌。
  2. 客戶端返回將令牌發送到服務器進行驗證。
  3. 如果服務器收到與經過身份驗證的用戶的標識不匹配的令牌,將拒絕請求。

熟悉ASP.NET和ASP.NET Core的同學應該都不陌生,因為在ASP.NET時期就有防止XSRF攻擊的方法,ASP.NET MVC中,IHtmlHelper.BeginForm默認情況下生成防偽令牌,而ASP.NET Core中,使用FormTagHelper默認也會生成防偽令牌的。

解決方案

Form表單提交

TagHelper用法:

<form asp-controller="Manage" asp-action="ChangePassword" method="post">
    ...
</form>

HtmlHelper 生成Form的用法:

@using (Html.BeginForm("ChangePassword", "Manage"))
{
    ...
}

普通html form表單用法:

<form action="/" method="post">
    @Html.AntiForgeryToken()
</form>

那么在Razor渲染之后,表單中就會生成一個隱藏的表單字段:

<input name="__RequestVerificationToken" type="hidden" value="CfDJ8NrAkS ... s2-m9Yw">

那么Ajax中要怎么處理呢?

官方文檔雖然有提到Ajax的處理方法,但是它指的Ajax是js原生實現XMLHttpRequest,而不是我們一般所認識的JQuery.ajax。所以本文就要介紹一下在使用JQuery.ajax時的全局配置。

場景一、從普通表單獲取Antiforgery Token

這種方法跟上面提到的Form表單提交一致,只要把所生成的隱藏的表單字段也一並提交到服務器即可。


$.ajax({
    url:"/Manage/ChangePassword",
    type:"post"
    data: { "__RequestVerificationToken":"CfDJ8NrAkS ... s2-m9Yw" }
})

但是這種方法有個弊端,就是需要配置的東西很多,又要在Contorller中加[ValidateAntiForgeryToken]特性,又要在表單中處理使其生成隱藏字段。

有沒有更方便的方法?當然有!而且即使是文檔中號稱自動防范 XSRF/CSRF的Razor Pages都同樣需要!因為它並沒有處理Ajax的場景。

場景二、全局配置,自動處理

全局獲取Forgery Token

全局(每個頁面)獲取Forgery Token就是文檔中提到的注入Microsoft.AspNetCore.Antiforgery.IAntiforgery並調用GetAndStoreTokens方法,但是由於需要達到全局獲取,我需要把這個方法的調用寫到布局頁,如默認MVC模版的Views/Shared/_Layout.cshtml

@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@functions{
    public string GetAntiXsrfRequestToken()
    {
        return Xsrf.GetAndStoreTokens(Context).RequestToken;
    }
}

<script>
    var csrfToken = '@GetAntiXsrfRequestToken()';
</script>

Ajax全局配置

JQuery.ajax里全局設置頭部的方法是$.ajaxSetup,按照文檔,把所需的頭部字段RequestVerificationToken配置上上面獲取到的令牌變量csrfToken,即可實現在每個Ajax請求都帶有Forgery Token。

(function (window, document, $) {
    $.ajaxSetup({
        headers: {
            'RequestVerificationToken': csrfToken
        }
    });
})(window, document, jQuery);

總結

雖然現在流行前后端分離了,包括我在內,也用上高大上的React、Angular、Vue等優秀框架,Github前端也把JQuery去掉了,但是Razor在ASP.NET Core中的份量有增無減,2.0版本帶來了更輕量的Razor Pages, 因此Razor+JQuery的熱度不會那么快退去,希望這篇文章能給大家在Razor+JQuery技術的使用過程中帶來一點參考價值。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM