【问题标题】:The anti-forgery token could not be decrypted even in localhost?即使在本地主机中也无法解密防伪令牌?
【发布时间】:2014-08-26 18:48:46
【问题描述】:

即使我在 localhost 中运行,我的 mvc 网站也会给我这个错误:

无法解密防伪令牌。如果此应用程序由 Web Farm 或群集托管,请确保所有计算机都运行相同版本的 ASP.NET 网页,并且配置指定显式​​加密和验证密钥。 AutoGenerate 不能在集群中使用。

我使用了这个机器密钥:

<machineKey compatibilityMode="Framework20SP1" validationKey='AC0DA63E787522E3BA5D47D8FA0A46EB68BB89A35C6353D5E8D3D5CA416D0DA607E56C6D0861ED3B7194C3ED74C0CE79FE4CE2909F34A6CFBDE134C1A094CA40' decryptionKey='A68360896EF374401123C6C222A7AAD8D430DB4DE34938E1' validation='SHA1'/>

但还是没有用。另外,我从第三方提取了这个机器密钥。我知道这不安全但微软的方式太复杂了:使用powershell生成它?复杂的。然后使用IIS?我的 IIS8 没有显示 machinekey 模块。所有这些东西到底是怎么回事。

好的,可能错误是由多个@html.antiforgerytoken 引起的。嗯,我确实有两个防伪令牌,但是当我删除其中一个时,错误仍然存​​在。

我对这个问题感到非常沮丧。我希望有人会好心帮忙。相信那些 MVC 用户在开发 MVC 网站的时候也遇到过这种情况。就我而言,我只是一个新手,这是我部署的第一个 MVC 网站。

感谢您的帮助

更新

控制器:

// POST: /Account/Manage
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Manage(ManageUserViewModel model)
    {
        bool hasPassword = HasPassword();
        ViewBag.HasLocalPassword = hasPassword;
        ViewBag.ReturnUrl = Url.Action("Manage");
        if (hasPassword)
        {
            if (ModelState.IsValid)
            {
                IdentityResult result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword, model.NewPassword);
                if (result.Succeeded)
                {
                    return RedirectToAction("Manage", new { Message = ManageMessageId.ChangePasswordSuccess });
                }
                else
                {
                    AddErrors(result);
                }
            }
        }
        else
        {
            // User does not have a password so remove any validation errors caused by a missing OldPassword field
            ModelState state = ModelState["OldPassword"];
            if (state != null)
            {
                state.Errors.Clear();
            }

            if (ModelState.IsValid)
            {
                IdentityResult result = await UserManager.AddPasswordAsync(User.Identity.GetUserId(), model.NewPassword);
                if (result.Succeeded)
                {
                    return RedirectToAction("Manage", new { Message = ManageMessageId.SetPasswordSuccess });
                }
                else
                {
                    AddErrors(result);
                }
            }
        }

        // If we got this far, something failed, redisplay form
        return View(model);
    }

查看:

@using percobaan2.Models;
@using Microsoft.AspNet.Identity;
@{
ViewBag.Title = "Manage Account";
Layout = "~/Views/Shared/_LayoutManage.cshtml";
}

<div class="row-fluid">
<div class="span4 offset4 blog-details">

    <p class="text-success">@ViewBag.StatusMessage</p>

    @using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
    {
        @Html.AntiForgeryToken()
        @Html.ValidationSummary(true)

        <article class="center">

            @if (ViewBag.HasLocalPassword)
            {
                @Html.Partial("_ChangePasswordPartial")
            }
            else
            {
                @Html.Partial("_SetPasswordPartial")
            }

        </article>
    }
</div>
</div>

@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}

布局:

<!DOCTYPE html>
<html lang="en">
<head>
<!-- META DATA -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">

<meta name="description" content="@ViewBag.WebsiteTitle">

<title>@ViewBag.Title - @ViewBag.WebsiteTitle</title>

<link rel="shortcut icon" href="assets/images/ico/favicon.png">

@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")

<!-- GOOGLE WEB FONTS -->
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,700,600,300,800' rel='stylesheet' type='text/css'>
</head>
<body>

<!-- NAVIGATION -->
<nav class="fixed-top fixed-visable" id="navigation">
    <div class="container">
        <div class="row-fluid">
            <div class="span12 center">
                <!-- MOBILE MENU BUTTON -->
                <div class="mobile-menu" data-toggle="collapse" data-target=".nav-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </div>
                <!-- END MOBILE MENU BUTTON -->
                <!-- MAIN MENU -->
                <ul id="main-menu" class="nav-collapse collapse">
                    <li><a href="@Url.Action("Edit", "Home", new { Area = "Admin", id = 1 })">Home</a></li>
                    <li><a href="@Url.Action("Index", "Slide", new { Area = "Admin" })">Tagline</a></li>
                    <li><a href="@Url.Action("Index", "Division", new { Area = "Admin" })">Division</a></li>
                    <li><a href="@Url.Action("Index", "Contact", new { Area = "Admin" })">Yahoo</a></li>
                    <li><a href="@Url.Action("Index", "Email", new { Area = "Admin" })">Email</a></li>
                    <li><a href="@Url.Action("Index", "Product", new { Area = "Admin" })">Product</a></li>
                    <li><a href="@Url.Action("Index", "Category", new { Area = "Admin" })">Category</a></li>
                    <li><a href="@Url.Action("Index", "Producer", new { Area = "Admin" })">Producer</a></li>
                    <li><a href="@Url.Action("Index", "Unit", new { Area = "Admin" })">Unit</a></li>
                    <li><a href="@Url.Action("Index", "Activity", new { Area = "Admin" })">Activity</a></li>
                    @*@Html.Partial("_LoginPartial")*@
                </ul>
                <!-- END MAIN MENU -->
            </div>
        </div>
    </div>
</nav>
<!-- END NAVIGATION -->
<!-- PAGE | BLOG -->
<div class="pages page-blog-list" id="page-blog-list">
    <div class="container">
        <!-- Header -->
        <header id="headerUpper" class="headerAdmin">
            <h4 class="line-divider">Admin</h4>
            <h1>Change Password</h1>
        </header>
        <!-- End Header -->

            @RenderBody()

    </div>
</div>
<!-- END PAGE | BLOG -->

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

部分登录:

@using Microsoft.AspNet.Identity
@if (Request.IsAuthenticated)
{
using (Html.BeginForm("LogOff", "Account", new { Area = "" }, FormMethod.Post, new { id = "logoutForm" }))
{
    @Html.AntiForgeryToken()

    <li>
        @Html.ActionLink("Account", "Manage", "Account", new { Area = "" }, htmlAttributes: new { title = "Manage" })
    </li>

    <li>
        <a href="javascript:document.getElementById('logoutForm').submit()">
            Log off
        </a>
    </li>

    @*<li>
            @Html.ActionLink("Account", "Manage", "Account", new { Area = "" }, htmlAttributes: new { title = "Manage", @class = "phoneNumber" })
        </li>

        <li>
            <a href="javascript:document.getElementById('logoutForm').submit()" class="phoneNumber logOffPadding">
                Log off
            </a>
        </li>*@

}
}
else
{
@*@Html.ActionLink("Register", "Register", "Account", new { Area = "" }, htmlAttributes: new { id = "registerLink", @class = "phoneNumber" })*@

<li>
    @Html.ActionLink("Log in", "Login", "Account", new { Area = "" }, htmlAttributes: new { id = "loginLink", @class = "phoneNumber logInPadding" })
</li>
}

.NET 版本:4.5

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-5 machinekey


    【解决方案1】:

    在我的情况下,这是由于防伪令牌以相同的形式应用了两次。 参考https://stackoverflow.com/a/28620686/662403

    【讨论】:

    • 我遇到了同样的问题:在同一个表单中两次调用 @Html.AntiForgeryToken 导致所有提交失败。感谢您的提示。
    【解决方案2】:

    您使用的是 IIS 还是 IIS Express?如果您使用的是 ISS Express,您可能会在每次从 Visual Studio 中进行调试时生成一个新的“站点”。如果是这样,删除浏览器(对于本地主机)中的 cookie 是否可以解决问题? (cookies是存储认证信息的地方)

    如果您使用的是 ISS Express,您可能希望切换到 IIS 进行开发(您迟早要学习)

    如果您使用的是 IIS,您可能需要注册一个模块。我认为您的 web.config 中缺少以下行:

    <securityTokenHandlers>
       <add type="System.IdentityModel.Services.Tokens.MachineKeySessionSecurityTokenHandler, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
       <remove type="System.IdentityModel.Tokens.SessionSecurityTokenHandler, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    </securityTokenHandlers>
    

    查看以下链接:

    Configuring Machine Key protection of session tokens

    Using WIF Session tokens

    话虽如此,这令人困惑,但有趣的是,当您创建一个新的 MVC 项目时,这些东西开箱即用,您可能想追踪您所做的更改以阻止它工作。需要机器钥匙吗?您是要在服务器场还是负载平衡环境中运行它。

    我们在使用 Azure 并从登台切换到生产时遇到了同样的问题,因为两台机器不同。我们最终使用 ssl 证书签署了我们的身份验证令牌,因此我们避免共享机器密钥。

    附:发布您的 web.config 可能有助于诊断此问题。

    【讨论】:

      【解决方案3】:

      确保您的项目已启用 SSL。

      即使您使用第三方生成的机器密钥。

      【讨论】:

        猜你喜欢
        • 2017-07-21
        • 2023-03-30
        • 2020-03-09
        • 2016-03-23
        • 1970-01-01
        • 1970-01-01
        • 2018-06-01
        • 2017-06-25
        相关资源
        最近更新 更多