在登录页面上覆盖防伪标记错误

时间:2016-05-27 07:45:36

标签: c# asp.net-mvc security authentication asp.net-mvc-5

我的网站收到大量以下错误:

  

提供的防伪令牌适用于不同的声明   用户比当前用户。

     

防伪cookie令牌和表单字段令牌不匹配。

如果防伪令牌不是针对用户而是在登录页面上包含用户,我想阻止该网站抛出错误,例如:

  

提供的防伪令牌适用于用户“”,但目前   用户是“加勒特”。

我不希望此例外适用于登录页面以外的任何其他页面。所以我不想将AntiForgeryConfig.SuppressIdentityHeuristicChecks = true;添加到整个网站。我还想让网站尽可能安全,因为它包含HIPAA数据。 我可以做些什么来尽可能保证其安全,但仍尝试在登录页面上防止此错误,因为这会让用户难以使用?

该站点托管在负载平衡服务器上,但我认为这不是问题。我认为错误主要是由于使用浏览器的后退按钮,在登录前打开登录页面一段时间,已经登录或多次登录。还有一些用户通过可能没有加载页面的应用程序访问它,只是尝试发布登录信息。

所以,请让我知道在尽可能安全的同时防止登录页面出现此错误的最佳选择是什么?

4 个答案:

答案 0 :(得分:5)

我最终做了什么,似乎在提供相同安全性的同时工作,是在检查用户是否已登录后手动检查防伪令牌。

    [HttpPost]
    [AllowAnonymous]
    //[ValidateAntiForgeryToken]
    [OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")]
    public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
    {
        // Skip the login process if the user is already logged in
        if (User.Identity.IsAuthenticated) 
        {
            return RedirectToAction("Index", "Home");
        }
        // Check the anti forgery token now
        System.Web.Helpers.AntiForgery.Validate();
        ...

答案 1 :(得分:2)

有来自某个用户的并发登录尝试的答案:

How can I fix anti-forgery token was meant for user "", but the current user is "xxxx " error

如果在用户填写登录页面的时间过长时出现AntiForgeryToken异常,只需重定向到该页面并显示一条消息,说明他/她的会话(即安全令牌)已过期。

[HttpPost]
[ValidateAntiForgeryToken]
[HandleError(View="Login", ExceptionType = typeof(HttpAntiForgeryException))]
public ActionResult Login(LoginModel model)
{
     // some login processing stuff
}

如果异常来自用户的单击后退按钮,请在客户端提供JS功能,以防止仅在登录页面上的后退按钮操作

<body onload="window.history.forward()">...</body>

// or wrap it inside a function
<script type="text/javascript">
function noBackOnLogin() {
        window.history.forward();
        history.pushState(null, document.title, url); // if you want to include Mobile Safari, see https://stackoverflow.com/a/34337617/6378815
    }
</script>
<body onload="noBackOnLogin();" onpageshow="if (event.persisted) noBackOnLogin();">...</body>

对于某个用户已登录的另一种情况,请重定向到指示其用户名的索引或某个页面(使用User.Identity.Name)。

我希望这个解释很有用。

答案 2 :(得分:0)

要回答@ Michael_B的担忧,你如何改变Garrett解决方案的这一部分:

    // Skip the login process if the user is already logged in
    if (User.Identity.IsAuthenticated) 
    {
        return RedirectToAction("Index", "Home");
    }
    // Check the anti forgery token now
    System.Web.Helpers.AntiForgery.Validate();
    ...

到此:

    // if not authenticated, check anti forgery token now:
    if (!User.Identity.IsAuthenticated) 
    {
        System.Web.Helpers.AntiForgery.Validate();
    }
    // run rest of login process normally

    ...

答案 3 :(得分:0)

我使用自定义属性来处理异常,并将用户重定向到主页(如果它是HttpAntiForgeryToken),而不是检查User.Identity.IsAuthenticated

我相信这可以避免使用其他方法带来的任何潜在安全隐患

public override void OnException(ExceptionContext filterContext)
    {
        var controllerName = (string)filterContext.RouteData.Values["controller"];
        var actionName = (string)filterContext.RouteData.Values["action"];
        var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
        if (filterContext.Exception is HttpAntiForgeryException)
        {
            filterContext.Result = new RedirectToRouteResult(
                new RouteValueDictionary
                {
                    { "action", "Index" },
                    { "controller", "Home" }
                });

            filterContext.ExceptionHandled = true;
        }
}