自写过滤器替代ValidateAntiForgeryToken解决asp.net mvc关于提供的防伪标记适用于其他基于声明的用户,而不适用于当前用户的错误

以前写过一篇 asp.net mvc关于提供的防伪标记适用于其他基于声明的用户,而不适用于当前用户错误的处理 的博文,在那篇博文最后留下了遗憾,在那篇博文中自定义的过滤器需要在action 中调用两次,才能避免出现关于提供的防伪标记适用于其他基于声明的用户,而不适用于当前用户这样的错误提示。调用的代码是这样的:

[HttpPost]
[AllowAnonymous]
[LoginAuthorize]
[ValidateAntiForgeryToken]
[LoginAuthorize]
public async Task Login(LoginViewModel model, string returnUrl)


可以看到,LoginAuthorize 在action 上被调用了两次。因此打算以后有空的话自己写一个 ValidateAntiForgeryToken 来彻底解决此问题。近几天刚好有空,因此打算尝试解决此问题。原以为会很复杂,不太容易解决。但实际做的过程当中却很容易。自定义过滤器替代ValidateAntiForgeryToken 没有想象中的难。实现的代码如下:

/// 
    /// 自定义AntiForgeryToken校验
    /// 
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class CustomerValidateAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter
    {

        internal Action ValidateAction
        {
            get;
            private set;
        }

        public CustomerValidateAntiForgeryTokenAttribute() : this(new Action(AntiForgery.Validate))
        {
        }

        internal CustomerValidateAntiForgeryTokenAttribute(Action validateAction)
        {
            this.ValidateAction = validateAction;
        }

        public void OnAuthorization(AuthorizationContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException("filterContext");
            }
            try
            {

                this.ValidateAction();
            }
            catch (Exception ex)
            {
                EventLog.WriteLog(ExceptionHelper.GetErrorMessageByLog(ex));
                //string url = filterContext.HttpContext.Request.UrlReferrer.ToString();
                //EventLog.WriteLog(url);
                filterContext.Result = new RedirectResult("/account/login", true);
                return;
                //throw;
            }

        }


 调用方法:

 [HttpPost]
        [AllowAnonymous]
        //[LoginAuthorize]
        [SXF.Utils.MVC.CustomerValidateAntiForgeryToken]
        //[LoginAuthorize]
        public async Task Login(LoginViewModel model, string returnUrl)

前台的cshtml中仍然使用

@Html.AntiForgeryToken()

不用做任何改变

你可能感兴趣的:(asp.net,MVC,C#)