[英]ASP.NET MVC HTML.AntiForgeryToken() with multiple AJAX requests from one page
[英]Alternative way to provide CSRF Token instead using @Html.AntiForgeryToken() in ASP.Net MVC
我正在使用ASP.Net MVC
后端處理一個有angular 2
應用程序。 為此, index.cshtml
包含了@Html.AntiForgeryToken();
所以我得到一個隱藏的輸入元素,其中Token作為其值。 在我的前端,我可以抓住這個令牌並將其用於我的請求。 到現在為止還挺好。
現在,由於用戶信息用於在后端生成令牌,我必須在某些場合切換令牌。 這個問題在這里描述了問題 。
現在因為我不想在我的應用程序中進行整頁重新加載,我必須使用一種解決方法。 為此,我在后端創建了一個局部視圖,它只是使用@Html.AntiForgeryToken();
此輸入@Html.AntiForgeryToken();
使用像這樣的簡單方法作為ActionResult
:
public ActionResult GetAntiForgery()
{
return PartialView("~/Views/Home/AntiForgery.cshtml");
}
登錄/注銷后,我從我的前端調用此函數並替換我現有的AntiForgery input element
的值,如下所示:
getAntiForgery(url:string) {
return this._http.get(url)
.map((response:any) => {
let originalXsrfElement = <HTMLInputElement>document.querySelector('[name=__RequestVerificationToken]');
let body = response._body;
if(body) {
let helperElem = document.createElement('div');
helperElem.innerHTML = body;
let helperInputElem = <HTMLInputElement>helperElem.firstChild;
originalXsrfElement.value = helperInputElem.value;
}
return response;
});
}
我甚至不能告訴你最讓我煩惱的是什么。 我討厭提出一個額外的請求(但不要在這里深入討論)但對我來說更糟糕的是我必須要求一些東西,得到一個html字符串並且必須從中提取令牌字符串。
如果我是后端人,我會殺死前端人(我..)甚至考慮創建一個額外的局部視圖,創建一個額外的方法,並始終在登錄/注銷而不是一個請求。
有沒有更好的辦法? 例如,我想調用一個方法,該方法只使用正確的令牌而不是HTML snippet
發出JSON
。 更好的是,在后端的現有JsonResult
方法中,我想將新的CSRF Token
添加為屬性。
我不是一個后端架構師,所以一般來說我可能會有一些錯誤,但我的后端同事不介意我在那里做什么所以它不應該那么遙遠。
任何提示都表示贊賞。
您可以在操作中使用AntiForgery.GetToken
在返回的JSON上設置一些屬性:
string cookieToken, formToken;
AntiForgery.GetTokens(null, out cookieToken, out formToken);
json.RequestVerificationToken = cookieToken + ":" + formToken;
然后,將其傳遞回下一個AJAX請求的標頭:
$.ajax("/my/awesome/url", {
type: "post",
contentType: "application/json",
data: { ... },
dataType: "json",
headers: {
'RequestVerificationToken': requestVerificationToken
}
});
由於它不再由cookie處理,因此您不能只使用標准的ValidateAntiForgeryToken
屬性。 您需要手動檢查標頭並驗證它。 但是,您應該能夠創建可以使用的自定義屬性:
AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public sealed class ValidateAntiForgeryTokenFromHeaderAttribute : FilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
var request = filterContext.HttpContext.Request;
string cookieToken = "";
string formToken = "";
IEnumerable<string> tokenHeaders;
if (request.Headers.TryGetValues("RequestVerificationToken", out tokenHeaders))
{
string[] tokens = tokenHeaders.First().Split(':');
if (tokens.Length == 2)
{
cookieToken = tokens[0].Trim();
formToken = tokens[1].Trim();
}
}
AntiForgery.Validate(cookieToken, formToken);
}
}
然后,只需使用[ValidateAntiForgeryTokenFromHeader]
裝飾您的操作。
[改編自http://www.asp.net/web-api/overview/security/preventing-cross-site-request-forgery-csrf-attacks的代碼]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.