MVC 4提供的防伪标记是为用户""设计的,但当前用户是"user"。

23
我最近发布了一个使用MVC 4Entity Framework 5构建的Web应用程序。这个MVC应用程序使用Razor Views
我注意到使用Elmah时,当用户登录应用程序时,有时会出现以下错误。
The provided anti-forgery token was meant for user "" but the current user is "user"
我已经进行了一些研究,试图解决这个问题,但似乎没有什么对我起作用的。请查看下面的登录视图和相应的控制器操作

Razor视图

@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>

}    
}

控制器

[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
      }

}

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

非常感谢您的帮助。

谢谢。


4
我认为这里已经有答案了。https://dev59.com/3mUp5IYBdhLWcg3w5Kk6 - Moin
你检查了这个答案吗?https://dev59.com/3mUp5IYBdhLWcg3w5Kk6 - binard
如果从登录操作中删除AllowAnonymous,则不会调用登录操作(“因为用户尚未登录”)。 - Vishal Shori
解决方案在这里:https://dev59.com/3mUp5IYBdhLWcg3w5Kk6#47868435 - A. Morel
3个回答

21

1
同样的情况。来自链接问题中最受欢迎的答案摘录:我只是删除了验证属性。我的网站始终是SSL,并且我对风险并不过分担心。我现在只需要它正常工作。另一个解决方案是使用JavaScript禁用按钮。 - Jerther
5
@Jerther:不要移除验证属性,特别是在登录页面上:http://security.stackexchange.com/questions/2120/when-the-use-of-a-antiforgerytoken-is-not-required-needed - Lukas

11

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

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

如果您想关闭此功能,请在Global.asax文件中的Application_Start方法中添加AntiForgeryConfig.SuppressIdentityHeuristicChecks = true;

当防伪标记验证失败时,您的网站将抛出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);
    }
}

更多信息:

防伪令牌是给用户“”用的,但当前用户是“username”

Html.AntiForgeryToken - 在安全性和可用性之间取得平衡


AntiForgeryConfig.SuppressIdentityHeuristicChecks 设置为 true 会有什么问题吗? - mxmissile
没有问题,这个设置是正确的。如果用户凭据已更改,则会出现此问题。 - Mohsen Esmailpour
我实际上更喜欢这个解决方案,因为它保持了安全检查并正确地通知用户,但不幸的是,很难阻止用户双击或按浏览器返回按钮返回到登录页面或其他页面。 - barnacle.m

0

当用户登录后,然后在主页上点击返回按钮回到登录页面,再以不同的用户身份登录时,我遇到了同样的问题:

  • 用户登录
  • 然后在主页上点击返回按钮回到登录页面
  • 用户以不同的用户身份登录
  • 这导致了异常:提供的防伪令牌是为用户“”而不是当前用户“user”而设计的

我发现这只会在IE浏览器中出现,并通过做一些事情来解决它。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接