AntiForgery.Validate()vs ValidateAntiForgeryToken

Chr*_*ill 9 antiforgerytoken asp.net-mvc-4

方法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());
    }
Run Code Online (Sandbox Code Playgroud)

这可以防止在系统因登录过期而退出时抛出Anti Forgery异常.我只想确定AntiForgery.Validate()将执行与ValidateAntiForgeryToken相同的任务.

我正在使用额外的异常处理程序来捕获此异常.然而问题仍然是Elmah仍然记录了这个异常,而且我收到了许多消息.

小智 14

似乎两种方法都会验证表单中存在的AntiForgeryToken.我检查了程序集,ValidateAntiForgeryTokenAttribute确实调用了AntiForgery.Validate方法来进行验证.当验证失败时,这两种方法都会抛出HttpValidateAntiForgeryException.因此,对于他们是否执行相同任务的简短回答是肯定的.

在OnAuthorization方法中,ValidateAntiForgeryTokenAttribute在MVC执行周期的早期验证令牌,这是一个细微的差别.如果在执行AntiForgeryToken.Validate()检查之前在控制器操作中执行资源密集型任务,这可能会对性能产生影响.

另外需要注意的是,您可能需要为每个HttpPost操作创建以下代码,从而为自己创建额外的工作(更不用说在省略时可能存在的安全漏洞)

if (User.Identity.Name != "")
{
    System.Web.Helpers.AntiForgery.Validate();
    WebSecurity.Logout();
}
Run Code Online (Sandbox Code Playgroud)

通过创建以下属性并使用它来装饰这些post方法,您将拥有所需的功能,并且不需要在每个后期操作中都具有上述代码

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;
            }
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

最后一点,AntiForgery验证中的例外是正常的.这是因为AntiForgery.Validate方法在验证失败时抛出HttpValidateAntiForgeryException.正如您在上面的代码中看到的,我已经捕获了此异常并在完成注销后重新抛出它.