asp.net-mvc MVC 4 提供的防伪令牌适用于用户“”,但当前用户是“用户”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20326990/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 03:21:49  来源:igfitidea点击:

MVC 4 provided anti-forgery token was meant for user "" but the current user is "user"

asp.net-mvcasp.net-mvc-4razorantiforgerytoken

提问by tcode

I've recently put Live a web application which was built using MVC 4and Entity Framework 5. The MVCapplication uses Razor Views.

我最近在 Live 上发布了一个使用MVC 4Entity Framework 5构建的 Web 应用程序。该MVC应用程序使用剃刀意见

I noticed using Elmahthat when users are logging into the application, sometimes they are getting the following error

我注意到使用Elmah 时,当用户登录应用程序时,有时他们会收到以下错误

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

I've done a bit of research already on how to fix this issue, but nothing seems to work for me. Please see my Login Viewand corresponding Controller Actionsbelow.

我已经对如何解决这个问题进行了一些研究,但似乎对我没有任何作用。请在下面查看我的登录视图和相应的控制器操作

Razor View

剃刀视图

@if (!HttpContext.Current.User.Identity.IsAuthenticated)
{

using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

     <div class="formEl_a">

        <fieldset>
            <legend>Login Information</legend>

            <div class="lbl_a">
                Email
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(m => m.Email, new { @class = "inpt_a" })<br />
                @Html.ValidationMessageFor(m => m.Email)
            </div>

            <div class="lbl_a">
                @Html.LabelFor(m => m.Password)
            </div>
            <div class="editor-field sepH_b">
                @Html.PasswordFor(m => m.Password, new { @class = "inpt_a" })<br />
                @Html.ValidationMessageFor(m => m.Password)
            </div>


        </fieldset>
    </div>
    <br />
      <p>
            <input type="submit" value="Log In" class="btn btn_d sepV_a" />
        </p>

}    
}

Controller

控制器

[AllowAnonymous]
public ActionResult Login()
{
     return View();
}

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
     if (ModelState.IsValid && _accountService.Logon(model.Email, model.Password, true))
     {
          //Validate
     }
     else
     {
          // inform of failed login
      }

}

I thought this all looked OK, but still the error persists. Does any have any ideas on how to fix this problem?

我认为这一切看起来都不错,但错误仍然存​​在。有没有关于如何解决这个问题的任何想法?

Your help is greatly appreciated.

非常感谢您的帮助。

Thanks.

谢谢。

回答by ganders

I believe this is occurring because the users are double-clicking the submit button on the form. At least that's EXACTLY the case on my site.

我相信这是因为用户双击了表单上的提交按钮。至少在我的网站上确实如此。

Troubleshooting anti-forgery token problems

对防伪令牌问题进行故障排除

回答by Mohsen Esmailpour

The validation code that runs against an AntiForgeryToken also checks your logged in user credentials haven't changed – these are also encrypted in the cookie. This means that if you logged in or out in a popup or another browser tab, your form submission will fail with the following exception:

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

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

You can turn this off by putting AntiForgeryConfig.SuppressIdentityHeuristicChecks = true;in Application_Startmethod inside Global.asaxfile.

您可以通过将关闭这个功能AntiForgeryConfig.SuppressIdentityHeuristicChecks = true;Application_Start方法内部Global.asax文件。

When a AntiForgeryToken doesn't validate your website will throw an Exception of type System.Web.Mvc.HttpAntiForgeryException. You can make this a little easier by at least giving the user a more informative page targeted at these exceptions by catching the HttpAntiForgeryException.

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

More info:

更多信息:

Anti forgery token is meant for user “” but the current user is “username”

防伪令牌适用于用户“”,但当前用户是“用户名”

Html.AntiForgeryToken – Balancing Security with Usability

Html.AntiForgeryToken – 平衡安全性和可用性

回答by Sandhya

I had the same problem when

我遇到了同样的问题

  • User logs in
  • Then on the Home Page the User hits Back Button to go back to Login
  • User logs in as a different User
  • This gave the exception : The provided anti-forgery token was meant for user "" but the current user is "user"
  • 用户登录
  • 然后在主页上,用户点击后退按钮返回登录
  • 用户以不同的用户身份登录
  • 这给出了例外:提供的防伪令牌适用于用户“”,但当前用户是“用户”

I found this was happening only in IE and I fixed it by doing a couple of things

我发现这仅在 IE 中发生,我通过做几件事来修复它

  1. Disabled output caching for the login page, because in debug mode I found that hitting the back button did not generate a new request to the Login page
  2. On the login page I added a check to see if the user is already authenticated, and if so logged out the user, and then redirected to the Login page again.

    [AllowAnonymous]
    [OutputCache(NoStore=true, Location=System.Web.UI.OutputCacheLocation.None)]
    public ActionResult Login)
    {
        if (HttpContext.Request.IsAuthenticated)
        {
            WebSecurity.Logout();
            Session.Abandon();
            return RedirectToAction("Login");
        }
    
        return View();
    }
    
  1. 禁用登录页面的输出缓存,因为在调试模式下我发现点击后退按钮没有生成对登录页面的新请求
  2. 在登录页面上,我添加了一个检查以查看用户是否已通过身份验证,如果是,则注销用户,然后再次重定向到登录页面。

    [AllowAnonymous]
    [OutputCache(NoStore=true, Location=System.Web.UI.OutputCacheLocation.None)]
    public ActionResult Login)
    {
        if (HttpContext.Request.IsAuthenticated)
        {
            WebSecurity.Logout();
            Session.Abandon();
            return RedirectToAction("Login");
        }
    
        return View();
    }