![](/img/trans.png)
[英]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.