我创建了一个反伪造属性类来装饰我的GenericBaseController
类:
[AttributeUsage(AttributeTargets.Class)]
public class ValidateAntiForgeryTokenAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
var request = filterContext.HttpContext.Request;
// Only validate POSTs
if (request.HttpMethod == WebRequestMethods.Http.Post)
{
// Ajax POSTs and normal form posts have to be treated differently when it comes
// to validating the AntiForgeryToken
if (request.IsAjaxRequest())
{
var antiForgeryCookie = request.Cookies[AntiForgeryConfig.CookieName];
var cookieValue = antiForgeryCookie != null
? antiForgeryCookie.Value
: null;
AntiForgery.Validate(cookieValue, request.Headers["__RequestVerificationToken"]);
}
else
{
new ValidateAntiForgeryTokenAttribute()
.OnAuthorization(filterContext);
}
}
}
}
(参考链接http://richiban.uk/2013/02/06/validating-net-mvc-4-anti-forgery-tokens-in-ajax-requests/)
一旦应用程序中的正常POST
调用完成(不是ajax),我总是得到StackOverflowException
。
没有ValidateAntiForgeryTokenAttribute
的应用程序运行正常。
如果我在这个类中调试代码,在发布请求之后,流程继续通过行
new ValidateAntiForgeryTokenAttribute()
.OnAuthorization(filterContext);
无限。
链接文章中的人确保此实现有效,因此我想知道为什么我会遇到此问题。
当请求不是ajax时,它真的应该创建一个新的ValidateAntiForgeryTokenAttribute
吗?
答案 0 :(得分:1)
归结为问题,您的代码是:
public class ValidateAntiForgeryTokenAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
if ( evaluateCondition() )
{}
else
{
new ValidateAntiForgeryTokenAttribute()
.OnAuthorization(filterContext);
}
}
}
问题
您的电话在else
区块中递归:
您调用该方法的类是ValidateAntiForgeryTokenAttribute
。
在您的else
区块中
new ValidateAntiForgeryTokenAttribute()
.OnAuthorization(filterContext);
,鉴于调用方法是
public override void OnAuthorization(AuthorizationContext filterContext)
表示您将继续在OnAuthorization
的新实例上调用ValidateAntiForgeryTokenAttribute
(即相同的方法)。
<强>解决方案强>
在您发布的示例中,情况略有不同 - 类的名称为ValidateAntiForgeryTokenOnAllPosts
,而您的名称为ValidateAntiForgeryTokenAttribute
,因此调用不是递归的,因为该方法不会调用自身相同的论点。
您有三种选择 - 我不确定哪种情况最适合您的情况(我想的是第一种情况):
将您的属性名称更改为ValidateAntiForgeryTokenOnAllPosts
以匹配the example you posted中的名称。
通过将块更改为
来明确声明您想要System.Web.Mvc.ValidateAntiForgeryTokenAttribute
new System.Web.Mvc.ValidateAntiForgeryTokenAttribute()
.OnAuthorization(filterContext);
由于您要覆盖ValidateAntiForgeryTokenAttribute
,您可以调用基本方法,即
else
{
base.OnAuthorization(filterContext);
}