方法System.Web.Helpers.AntiForgery.Validate(); 执行与[ValidateAntiForgeryToken]装饰完全相同的功能?
我正在考虑更改我的注销方法:
[HttpPost]
public virtual ActionResult LogOff()
{
if (User.Identity.Name != "")
{
System.Web.Helpers.AntiForgery.Validate();
WebSecurity.Logout();
}
return RedirectToAction(MVC.Account.Login());
}
这可以防止在系统因登录过期而退出时引发Anti Forgery异常。我只想确定AntiForgery.Validate()将执行与ValidateAntiForgeryToken相同的任务。
我正在使用额外的异常处理程序来捕获此异常。然而问题仍然是Elmah仍然记录了这个异常,而且我收到了许多消息。
答案 0 :(得分:14)
似乎两种方法都会验证表单中存在的AntiForgeryToken。我检查了程序集,ValidateAntiForgeryTokenAttribute确实调用了AntiForgery.Validate方法来进行验证。当验证失败时,这两种方法都会抛出HttpValidateAntiForgeryException。因此,他们是否执行相同任务的简短答案是肯定的。
在OnAuthorization方法中,ValidateAntiForgeryTokenAttribute在MVC执行周期的早期验证令牌存在细微差别。如果在执行AntiForgeryToken.Validate()检查之前在控制器操作中执行资源密集型任务,这可能会对性能产生影响。
另外需要注意的是,您可能要为自己创建额外的工作(更不用说省略时可能存在的安全漏洞),要求每个HttpPost操作都有以下代码
if (User.Identity.Name != "")
{
System.Web.Helpers.AntiForgery.Validate();
WebSecurity.Logout();
}
通过创建以下属性并使用它来装饰这些帖子方法,您将拥有所需的功能,而不需要在每个帖子操作中都包含上述代码
using System;
using System.Web.Mvc;
[AttributeUsage( AttributeTargets.Method | AttributeTargets.Class , AllowMultiple = false , Inherited = true )]
public class ValidateOrSignOutAntiForgeryTokenAttribute :
FilterAttribute ,
IAuthorizationFilter
{
public void OnAuthorization( AuthorizationContext filterContext )
{
if( filterContext == null )
{
throw new ArgumentNullException( "filterContext" );
}
if( filterContext.HttpContext.User != null &&
filterContext.HttpContext.User.Identity.Name != "" )
{
try
{
System.Web.Helpers.AntiForgery.Validate();
}
catch
{
WebSecurity.Logout();
throw;
}
}
}
}
最后一点,AntiForgery验证中的例外是正常的。这是因为AntiForgery.Validate方法在验证失败时抛出HttpValidateAntiForgeryException。正如您在上面的代码中看到的,我已经捕获了此异常并在完成注销后重新抛出它。