我们在登录页面上遇到了防伪标记的特定问题.如果用户只使用一个活动窗口登录,则一切正常,但是如果用户在两个不同的窗口中打开登录页面并从窗口A登录(没有问题将登录),则返回到此窗口中的窗口B登录用户将收到“未提供所需的防伪标记或无效”.
有没有办法绕过这个从视图/控制器动作中删除防伪标记?我们更愿意使用令牌以获得额外的安全性!
这与这个问题非常相似,但要求mvc2
MVC ValidateAntiForgeryToken multi-tabs problem
解决方法
MVC3或MVC4中的这种行为是按照设计的,但如上所述,它对用户不友好,但是在生产中,这个问题需要优雅地解决,应用程序需要处理这种奇怪的情况.此问题的解决方案是创建一个应用于登录帖子的过滤器,该过滤器将验证用户是否已登录并将其带到正确的页面,否则它们将保留在登录页面上.
/// <summary> /// Handle Antiforgery token exception and redirect to customer area if the user is Authenticated /// </summary> public class RedirectOnError : HandleErrorAttribute { /// <summary> /// Override the on exception method and check if the user is authenticated and redirect the user /// to the customer service index otherwise continue with the base implamentation /// </summary> /// <param name="filterContext">Current Exception Context of the request</param> public override void OnException(ExceptionContext filterContext) { if (filterContext.Exception is HttpAntiForgeryException && filterContext.HttpContext.User.Identity.IsAuthenticated) { // Set response code back to normal filterContext.HttpContext.Response.StatusCode = 200; // Handle the exception filterContext.ExceptionHandled = true; UrlHelper urlH = new UrlHelper(filterContext.HttpContext.Request.RequestContext); // Create a new request context RequestContext rc = new RequestContext(filterContext.HttpContext,filterContext.RouteData); // Create a new return url string url = RouteTable.Routes.GetVirtualPath(rc,new RouteValueDictionary(new { Controller = "CustomerArea",action = "Index" })).VirtualPath; // Check if there is a request url if (filterContext.HttpContext.Request.Params["ReturnUrl"] != null && urlH.IsLocalUrl(filterContext.HttpContext.Request.Params["ReturnUrl"])) { url = filterContext.HttpContext.Request.Params["ReturnUrl"]; } // Redirect the user back to the customer service index page filterContext.HttpContext.Response.Redirect(url,true); } else { // Continue to the base base.OnException(filterContext); } } }
这是使用示例
[HttpPost] **[RedirectOnError]** [ValidateAntiForgeryToken] public ActionResult logon(logonviewmodel model,UserSessionState session,string returnUrl) { ..... }