以前写过一篇 asp.net mvc关于提供的防伪标记适用于其他基于声明的用户,而不适用于当前用户错误的处理 的博文,在那篇博文最后留下了遗憾,在那篇博文中自定义的过滤器需要在action 中调用两次,才能避免出现关于提供的防伪标记适用于其他基于声明的用户,而不适用于当前用户这样的错误提示。调用的代码是这样的:
[HttpPost]
[AllowAnonymous]
[LoginAuthorize]
[ValidateAntiForgeryToken]
[LoginAuthorize]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
可以看到,LoginAuthorize 在action 上被调用了两次。因此打算以后有空的话自己写一个 ValidateAntiForgeryToken 来彻底解决此问题。近几天刚好有空,因此打算尝试解决此问题。原以为会很复杂,不太容易解决。但实际做的过程当中却很容易。自定义过滤器替代ValidateAntiForgeryToken 没有想象中的难。实现的代码如下:
/// <summary>
/// 自定义AntiForgeryToken校验
/// </summary>
[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<ActionResult> Login(LoginViewModel model, string returnUrl)
前台的cshtml中仍然使用
@Html.AntiForgeryToken()
不用做任何改变