2012-03-26 34 views
6

我们对登录页面上的防伪令牌存在特定问题。如果用户仅使用一个活动窗口登录,那么一切都很好,但是如果用户在两个不同的窗口中打开登录页面并从窗口A登录(无问题将会登录),并返回到此窗口中从窗口B登录用户将收到“所需的防伪标记未提供或无效”。Mvc3 Antiforgery令牌多选项卡

有没有办法解决这个问题,然后从视图/控制器动作中删除反伪造令牌?我们希望拥有令牌以增加安全性!

这是非常相似,这个问题然而这要求MVC2 MVC ValidateAntiForgeryToken multi-tabs problem

+0

我离开了你另一个答案的例子 - 我应该已经回答了我的问题! – 2013-09-03 16:28:38

回答

20

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

这是使用

​​
+0

我不明白如果用户没有登录会发生什么...因为保留在日志页面上可能会再次导致异常。 – ilans 2014-07-16 16:53:52

+2

回应IlanS - 代码 if(filterContext.Exception是HttpAntiForgeryException && filterContext.HttpContext.User.Identity.IsAuthenticated) 只会在用户登录时应用重定向,否则非认证用户的常规异常是抛出。 – MORCHARD 2015-04-23 14:54:53

+0

伟大的解决方案! – 2015-10-23 02:04:30

4

登录之后,所有以前的令牌是无效的。这就是它应该如何工作。纳兹接近正确的答案,除了cookie中的标记不存储用户名。只有表单中的令牌可以。正是由于这个问题:如果用户登录,所有现有的表单令牌都应该失效,但是使cookie本身无效将会太成问题并且用户不友好。