【问题标题】:Mvc3 Antiforgery token multi tabsMvc3 Antiforgery 令牌多选项卡
【发布时间】:2012-04-10 11:45:09
【问题描述】:

我们在登录页面上遇到了与防伪令牌有关的特定问题。如果用户仅使用一个活动窗口登录,则一切正常,但是如果用户在两个不同的窗口中打开登录页面并从窗口 A 登录(没有问题将登录),然后在此窗口中返回从窗口 B 登录用户将收到“未提供所需的防伪令牌或该令牌无效”。

除了从视图/控制器操作中删除防伪令牌之外,还有其他方法吗?我们希望拥有令牌以提高安全性!

这与这个问题非常相似,但是这是针对 mvc2 提出的 MVC ValidateAntiForgeryToken multi-tabs problem

【问题讨论】:

  • 我给你留下了另一个答案——我应该回答我自己的问题!

标签: asp.net-mvc asp.net-mvc-3 antiforgerytoken


【解决方案1】:

一旦您登录,之前的所有令牌均无效。这就是它应该如何工作的方式。 Naz 接近正确答案,除了 cookie 中的令牌不存储用户名。只有表单中的令牌可以。正是因为这个问题:如果用户登录,所有现有的 form 令牌都应该失效,但是使 cookie 本身失效会带来太多问题和用户不友好。

【讨论】:

    【解决方案2】:

    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)
            {
            .....
            }
    

    【讨论】:

    • 我不明白如果用户没有登录会发生什么......因为留在登录页面可能会再次导致异常。
    • 响应 IlanS - 代码 if (filterContext.Exception is HttpAntiForgeryException && filterContext.HttpContext.User.Identity.IsAuthenticated) 仅在用户登录时应用重定向,否则为常规异常未经过身份验证的用户被抛出。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-06
    • 2017-04-15
    • 1970-01-01
    相关资源
    最近更新 更多