【问题标题】:How to resolve: The provided anti-forgery token was meant for a different claims-based user than the current user如何解决:提供的防伪令牌适用于与当前用户不同的基于声明的用户
【发布时间】:2017-01-03 14:28:25
【问题描述】:

我收到此错误:

The provided anti-forgery token was meant for a different claims-based user than the current user.

我不知道如何纠正这个..

我有一个 MVC5 站点,在这个站点中我有一个登录页面。

这是它发生的场景。

  1. 用户 AAA 登录。(没有问题)
  2. 我试图访问用户无权访问的视图。
    • 我的班级用 Authorize(Roles="aa") 装饰
  3. 视图然后将用户注销并将其放回登录页面。
  4. 用户 AAA 登录。(这次我得到了上面提到的错误)

注意:
我正在使用 customErrors,这是我看到错误消息的地方。

当我注销用户时,我正在运行此方法:

[HttpGet]
public void SignOut()
{
    IAuthenticationManager authenticationManager = HttpContext.GetOwinContext().Authentication;
    authenticationManager.SignOut(MyAuthentication.ApplicationCookie);
}

我可能会在 SignOut 上遗漏一些东西吗?

更新:
这只是因为上面列出的第 2 步。
如果我登录,然后注销(调用相同的代码)然后重新登录,那么我没有这个问题。

【问题讨论】:

  • 尝试添加 [ValidateAntiForgeryToken] 属性
  • 当用户登录时,我的 post 方法中有这个。[HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken]

标签: c# asp.net-mvc


【解决方案1】:

我认为您忽略了发布一些相关代码。您拥有的Signout 操作返回void。如果您要直接在浏览器中访问此操作,则用户在退出后将获得一个空白页面,无法继续前进。因此,我只能假设您要么通过 AJAX 调用它,要么作为另一个操作的方法调用。

防伪在 MVC 中的工作方式是在用户机器上设置一个包含唯一生成令牌的 cookie。如果用户已登录,则他们的用户名将用于组成该令牌。为了在没有设置用户名的情况下获得新的 cookie,用户必须退出并且必须发生新的请求来设置新的 cookie。如果您只是将用户注销而不进行重定向或其他操作,则尚未设置新的无用户 cookie。然后,当用户发帖时,旧的基于用户的 cookie 被发回,而 MVC 正在寻找新的无用户 cookie,然后繁荣:这是你的例外。

就像我说的,您没有发布足够的代码来确定发生这种情况的确切原因或位置,但只需确保在用户注销后发出新请求,以便可以设置新 cookie。

【讨论】:

  • 感谢您的解释。在这种情况下,我没有进行重定向,这导致了我的问题。但是,当 Authorize 属性失败时,我仍然注意到一个问题,它会重定向到登录页面,但我不太确定它是如何做到的。 (它没有达到我的断点)
  • 我不太确定你在说什么。 AuthorizeAttribute 的默认行为是重定向到在 Web.config (ASP.NET Membership) 或 Identity 启动配置 (ASP.NET Identity) 中定义的 URL。它实际上并没有将用户注销,从技术上讲,您可以将他们带到 any 页面。标准是使用登录,因此用户有机会实际登录或使用具有访问权限的其他帐户进行身份验证。
  • 我仍在学习 MVC,但不知何故我有默认行为将用户注销。但是,当授权失败时,它会重复上述行为(将它们注销但没有重定向)。我创建了一个自定义授权,以便我可以处理这个并且它似乎可以工作。
【解决方案2】:

禁用防伪验证执行的身份检查。将以下内容添加到您的 Application_Start 方法中:

AntiForgeryConfig.SuppressIdentityHeuristicChecks = true.

【讨论】:

  • 当我添加该行时,我收到错误:提供的防伪令牌用于用户“AAA”但当前用户是“”
  • 不知道,但我的工作正常。在您的操作中尝试此操作 [OutputCache(NoStore=true, Duration = 0, VaryByParam= "None")]
  • AntiForgeryConfig 自动完成没有让我选择SuppressIdentityHeuristicChecks。我正在使用 Asp .NET Web API
  • 应该可能包含“设置此值时要小心。使用不当可能会在应用程序中打开安全漏洞”的注释。来自docs.microsoft.com/en-us/previous-versions/aspnet/…
【解决方案3】:

尝试:

public ActionResult Login(string modelState = null)
{
    if (modelState != null)
        ModelState.AddModelError("", modelState);

    return View();
}
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model)
{
    AuthenticationManager.SignOut();

    return RedirectToAction("Login", "Controller", new { modelState = "MSG_USER_NOT_CONFIRMED" });
}

【讨论】:

    【解决方案4】:

    在下一个视图加载之前,我可以通过多次单击登录按钮来重现。第一次单击后我禁用了登录按钮以防止出现错误。

    <button type="submit" onclick="this.disabled=true;this.form.submit();"/>
    

    【讨论】:

    • 如果网络问题导致服务器触发的重定向永远不会返回给用户,这最终会以用户敌对的方式失败。他们已在您的服务器上注销,并且没有错误;但据他们所知,注销失败并且由于按钮被禁用,他们无法再试一次。
    【解决方案5】:

    我有类似的问题。我在我的项目中的 2 处找到了此文本“@Html.AntiForgeryToken()”。其中一个将是在“视图文件”视图中 - test.cshtml。

        @using (Html.BeginForm())
        @Html.AntiForgeryToken()
        <div class="form-horizontal">
            <div class="form-group">
                @if (@Model.interviewed)
    ...
    

    我删除了这个代码行(“@Html.AntiForgeryToken()”)并且工作正常。

    PS:但我没有删除文件_LoginPartial.cshtml中的这段代码。 祝你好运!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-01
      • 2018-01-12
      • 2015-02-01
      • 2016-03-19
      • 2013-12-18
      • 2020-05-31
      • 2013-02-04
      相关资源
      最近更新 更多