【问题标题】:The anti-forgery token could not be decrypted & The anti-forgery cookie token and form field token do not match in deployment防伪令牌无法解密 & 防伪 cookie 令牌和表单字段令牌在部署中不匹配
【发布时间】:2015-12-20 07:52:01
【问题描述】:

我的部署服务器有时有这个问题,它让我发疯,因为我无法在本地主机中重现,我尝试在我的 web.config 中添加机器密钥,但没有运气所以远。

它只发生在登录页面。

我的布局:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")

</head>
<body>
    <form id="__AjaxAntiForgeryForm" action="#" method="post">
        @Html.AntiForgeryToken()
    </form>

    <div class="wcenter">
        @Html.Partial("_LoginPartial")
    </div>

    <br />

    <div class="wcenter">
        @RenderBody()
    </div>

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/jqueryval")
    @Scripts.Render("~/bundles/bootstrap")
    @Scripts.Render("~/bundles/pluginjs")
    @Scripts.Render("~/bundles/customjs")
    @RenderSection("scripts", required: false)
</body>
</html>

我的登录页面

@model LoginViewModel
@{
    ViewBag.Title = "Log in";
}

<h2>@ViewBag.Title.</h2>
            @using (Html.BeginForm("Login", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
            {
                @Html.AntiForgeryToken()

                @Html.LabelFor(m => m.Username)
                @Html.TextBoxFor(m => m.Username)
                @Html.ValidationMessageFor(m => m.Username)

                @Html.LabelFor(m => m.Password)
                @Html.PasswordFor(m => m.Password)
                @Html.ValidationMessageFor(m => m.Password)

                <input type="submit" value="LOGIN" />
            }

控制器:

    [AllowAnonymous]
    public ActionResult Login()
    {
        if (Request.IsAuthenticated)
        {
            return RedirectToAction("Index", "Home");
        }

        return View();
    }

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
    {
        if (Request.IsAuthenticated)
        {
            return RedirectToAction("Index", "Home");
        }

        if (!ModelState.IsValid)
        {
            return View(model);
        }

        var user = new ApplicationUser() { UserName = model.Username, Id = model.Username };
        var result = await UserManager.CheckPasswordAsync(user, model.Password);

        if (result == true)
        {
            if (UserManager.FindByName(user.UserName) == null)
            {
                var res = UserManager.Create(user);

                if (!res.Succeeded)
                {
                    ModelState.AddModelError("", res.Errors.FirstOrDefault());
                    return View(model);
                }
            }

            SignInManager.SignIn(user, true, true);
            return RedirectToAction("Index", "Home");
        }

        ModelState.AddModelError("", "Invalid login attempt.");
        return View(model);
    }

任何帮助将不胜感激。

【问题讨论】:

  • 奇怪的行为......你可以运行网络跟踪来检查请求表单参数中传递的__RequestAnitForgeryToken是否与你的html登录表单中生成的相同?
  • 好的,所以我做了一个小测试,发现它只有在我登录时才会发生,然后等待一段时间,直到它超时并尝试再次登录,这样我总是会收到错误The anti-forgery cookie token and form field token do not match.
  • 我认为您的问题是您的布局页面中的 @Html.AntiForgeryToken()。据我所知,您应该在用于将数据发回服务器的表单中包含此帮助程序。在您的布局页面中有一个空表单。
  • @warheat1990 - 似乎即使在超时的情况下,服务器也会对用户进行身份验证并在下次更新 Identity.IsAuthenticated 为 true ,因为初始防伪造令牌是发给匿名用户的,不会被服务器验证。

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


【解决方案1】:

这是因为您正在创建 2 个 Antiforgery 令牌,一个在表单内,另一个在您的局部视图中。所以有时创建的 cookie CSRF 与 CSRF 输入隐藏字段不匹配

【讨论】:

  • 那么我能做些什么来解决这个问题呢?我的 ajax 调用需要第二个令牌。
  • 您必须只保留一个对@Html.AntiForgeryToken() 的引用,对于您的ajax 调用,您可以搜索令牌,并放入您的标头请求。例如: var csrfToken = $('body').find('input[name="__RequestVerificationToken"]').val();
猜你喜欢
  • 1970-01-01
  • 2013-08-08
  • 2018-01-05
  • 2017-03-08
  • 1970-01-01
  • 2017-07-21
  • 2023-03-30
  • 2018-06-19
相关资源
最近更新 更多