C# AntiForgeryToken 属性在 mvc 应用程序中导致 StackOverflowException
C# AntiForgeryToken attribute causes StackOverflowException in mvc application
我已经创建了一个防伪属性 class 来装饰我的 GenericBaseController
class:
[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);
}
}
}
}
(参考 link http://richiban.uk/2013/02/06/validating-net-mvc-4-anti-forgery-tokens-in-ajax-requests/ )
一旦应用程序中的正常 POST
调用完成(不是 ajax),我总是会收到 WhosebugException
。
没有 ValidateAntiForgeryTokenAttribute
的应用程序工作正常。
如果我在这个 class 中调试代码,在 post 请求之后,流程继续通过行
new ValidateAntiForgeryTokenAttribute()
.OnAuthorization(filterContext);
无限。
linked 文章中的人保证此实现有效,所以我想知道为什么我会遇到这个问题。
当请求不是 ajax 时,它真的应该创建一个新的 ValidateAntiForgeryTokenAttribute
吗?
归结为问题,你的代码是:
public class ValidateAntiForgeryTokenAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
if ( evaluateCondition() )
{}
else
{
new ValidateAntiForgeryTokenAttribute()
.OnAuthorization(filterContext);
}
}
}
问题
您的调用在 else
块中递归:
您调用方法的 class 是 ValidateAntiForgeryTokenAttribute
。
在您的 else
区块中您有
new ValidateAntiForgeryTokenAttribute()
.OnAuthorization(filterContext);
其中,鉴于调用方法是
public override void OnAuthorization(AuthorizationContext filterContext)
意味着您将在 ValidateAntiForgeryTokenAttribute
.
的新实例上继续调用 OnAuthorization
(即相同的方法)
解决方案
在您发布的示例中,情况略有不同 - class 的名称是 ValidateAntiForgeryTokenOnAllPosts
而您的名称是 ValidateAntiForgeryTokenAttribute
,因此调用不是递归的,因为方法没有用相同的参数调用自己。
您有三个选项 - 我不确定哪个最适合您的情况(我在考虑第一个):
将您的属性名称更改为 ValidateAntiForgeryTokenOnAllPosts
以匹配 the example you posted 中的名称。
通过将块更改为 say
明确说明您想要 System.Web.Mvc.ValidateAntiForgeryTokenAttribute
new System.Web.Mvc.ValidateAntiForgeryTokenAttribute()
.OnAuthorization(filterContext);
因为你覆盖了ValidateAntiForgeryTokenAttribute
,你可以调用基本方法,即
else
{
base.OnAuthorization(filterContext);
}
我已经创建了一个防伪属性 class 来装饰我的 GenericBaseController
class:
[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);
}
}
}
}
(参考 link http://richiban.uk/2013/02/06/validating-net-mvc-4-anti-forgery-tokens-in-ajax-requests/ )
一旦应用程序中的正常 POST
调用完成(不是 ajax),我总是会收到 WhosebugException
。
没有 ValidateAntiForgeryTokenAttribute
的应用程序工作正常。
如果我在这个 class 中调试代码,在 post 请求之后,流程继续通过行
new ValidateAntiForgeryTokenAttribute()
.OnAuthorization(filterContext);
无限。
linked 文章中的人保证此实现有效,所以我想知道为什么我会遇到这个问题。
当请求不是 ajax 时,它真的应该创建一个新的 ValidateAntiForgeryTokenAttribute
吗?
归结为问题,你的代码是:
public class ValidateAntiForgeryTokenAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
if ( evaluateCondition() )
{}
else
{
new ValidateAntiForgeryTokenAttribute()
.OnAuthorization(filterContext);
}
}
}
问题
您的调用在 else
块中递归:
您调用方法的 class 是
ValidateAntiForgeryTokenAttribute
。在您的
else
区块中您有new ValidateAntiForgeryTokenAttribute() .OnAuthorization(filterContext);
其中,鉴于调用方法是
public override void OnAuthorization(AuthorizationContext filterContext)
意味着您将在
ValidateAntiForgeryTokenAttribute
. 的新实例上继续调用
OnAuthorization
(即相同的方法)
解决方案
在您发布的示例中,情况略有不同 - class 的名称是 ValidateAntiForgeryTokenOnAllPosts
而您的名称是 ValidateAntiForgeryTokenAttribute
,因此调用不是递归的,因为方法没有用相同的参数调用自己。
您有三个选项 - 我不确定哪个最适合您的情况(我在考虑第一个):
将您的属性名称更改为
ValidateAntiForgeryTokenOnAllPosts
以匹配 the example you posted 中的名称。通过将块更改为 say
明确说明您想要System.Web.Mvc.ValidateAntiForgeryTokenAttribute
new System.Web.Mvc.ValidateAntiForgeryTokenAttribute() .OnAuthorization(filterContext);
因为你覆盖了
ValidateAntiForgeryTokenAttribute
,你可以调用基本方法,即else { base.OnAuthorization(filterContext); }