浏览器上的防伪令牌问题,然后重新提交

时间:2015-09-28 05:39:31

标签: c# login asp.net-mvc-5 form-submit antiforgerytoken

在我的MVC5应用程序中,实现了防伪令牌。用户启动和登录时,它可以工作。如果用户在登录后单击浏览器并使用不同的凭据重新提交,则显示

The provided anti-forgery token was meant for user "xxxx", but the current user is "yyyy"

在登录控制器中,我尝试了类似

的内容
public ActionResult Index()
{
    if (User != null && (User.Identity.IsAuthenticated || User.Identity.Name != ""))
    {
        FormsAuthentication.SignOut();
        Session.Abandon();
        return RedirectToAction("Index");
    }
    return View();
}

但在这种情况下,系统不会触发操作。

2 个答案:

答案 0 :(得分:3)

当我们有防伪标记时,这很常见。

  
    

这种情况正在发生,因为防伪令牌将用户的用户名作为加密令牌的一部分嵌入,以便更好地进行验证。什么时候     你首先调用@ Html.AntiForgeryToken(),用户没有登录     因此令牌将在用户名之后有一个空字符串     用户登录,如果不替换防伪令牌,则不会     通过验证,因为初始令牌是匿名用户和     现在我们有一个具有已知用户名的经过身份验证的用户。

  
     

您有几个选项可以解决此问题:

     

1-就在这个时候让你的应用程序执行完整的POST以及何时执行   页面重新加载它将具有更新的防伪标记   用户名嵌入式。

     

2-只有@ Html.AntiForgeryToken()和右边的部分视图   登录后,执行另一个AJAX请求并替换现有的   防伪令牌与请求的响应。

     

3-只需禁用身份检查防伪验证即可   施行。将以下内容添加到Application_Start方法中:   AntiForgeryConfig.SuppressIdentityHeuristicChecks = true。

针对AntiForgeryToken运行的验证代码还会检查您登录的用户凭据是否未更改 - 这些也在Cookie中加密。这意味着,如果您在弹出窗口或其他浏览器选项卡中登录或注销,则表单提交将失败,并出现以下异常:

System.Web.Mvc.HttpAntiForgeryException (0x80004005):
The provided anti-forgery token was meant for user "xxxx", but the current user is "yyyy".

你可以通过放置AntiForgeryConfig.SuppressIdentityHeuristicChecks = true来关闭它;在Global.asax文件中的Application_Start方法中。

当AntiForgeryToken未验证您的网站时,将抛出类型为System.Web.Mvc.HttpAntiForgeryException的异常。您可以通过捕获HttpAntiForgeryException,至少为用户提供针对这些异常的信息更丰富的页面,从而使这更容易。

private void Application_Error(object sender, EventArgs e)
{
    Exception ex = Server.GetLastError();

    if (ex is HttpAntiForgeryException)
    {
        Response.Clear();
        Server.ClearError(); //make sure you log the exception first
        Response.Redirect("/error/antiforgery", true);
    }
}

Here是类似问题的SO线程。

additional参考。

如果有帮助,请选择此答案。感谢

答案 1 :(得分:0)

使用

装饰您的Login GET方法
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public ActionResult Login(...)

阻止页面被缓存。这将强制在没有先前登录的用户用户名的情况下创建新令牌。