asp.net-mvc 即使在本地主机中也无法解密防伪令牌?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24591082/
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:46:19  来源:igfitidea点击:

The anti-forgery token could not be decrypted even in localhost?

asp.net-mvcasp.net-mvc-5machinekey

提问by Ace Supriatna

Even though I am running in localhost, my mvc web site gives me this error:

即使我在本地主机上运行,​​我的 mvc 网站也给了我这个错误:

The anti-forgery token could not be decrypted. If this application is hosted by a Web Farm or cluster, ensure that all machines are running the same version of ASP.NET Web Pages and that the configuration specifies explicit encryption and validation keys. AutoGenerate cannot be used in a cluster.

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

I used this machinekey:

我使用了这个机器密钥:

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

But still no use. In addition, I extracted this machinekey from a third party. I know it is not safe but the microsoft way is too complicated: using powershell to generate it? complicated. Then using IIS? My IIS8 is not showing machinekey module. What on earth is going on with all of these stuff.

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

Okay, maybe the error is caused by a multiple @html.antiforgerytoken. Well, I had indeed two antiforgerytoken, but when I remove one of them, the error persisted.

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

I am so frustated with this problem. I hope someone will be kind enough to help. I believe those MVC users have been in this situation when developing MVC web site. In my case, I am just a newbie and this is my first MVC web site that is deployed.

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

thanks for you help

谢谢你的帮助

UPDATE

更新

controller:

控制器:

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

View:

看法:

@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")
}

Layout:

布局:

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

Login Partial:

登录部分:

@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 Vesion: 4.5

.NET 版本:4.5

回答by maurox

In my case it was caused by the anti-forgery token being applied twice in the same form. ref https://stackoverflow.com/a/28620686/662403

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

回答by themikola

Ensure you have SSL enabled on your project.

确保您的项目启用了 SSL。

Even if you using a third party generated machine key.

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

回答by Aran Mulholland

Are you using IIS or IIS Express? If you are using ISS Express you are probably generating a new 'site' every time you hit debug from Visual Studio. If so does deleting the cookies in the browser (for localhost) fix the problem? (the cookies are where the authentication information is stored)

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

If you are using ISS Express you might want to switch to IIS for development (You will have to learn it sooner or later)

如果您正在使用 ISS Express,您可能想切换到 IIS 进行开发(您迟早必须学习它)

If you are using IIS you may need to register a module. I think you are missing the following lines line from your web.config:

如果您使用的是 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>

Have a look at the following links:

看看以下链接:

Configuring Machine Key protection of session tokens

配置会话令牌的机器密钥保护

Using WIF Session tokens

使用 WIF 会话令牌

That being said this is confusing stuff, the funny thing is that this stuff works out of the box when you create a new MVC project, you might want to track down what you changed to stop it working. Do you need to have a machine key? Are you going to be running this on a server farm or in a load balanced environment.

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

We have had the same issue when using Azure and swapping from staging to production as both machines were different. We ended up signing our authentication tokens with a ssl certificate so we avoided sharing a machine key.

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

P.S. Posting your web.config would probably help in diagnosing this problem.

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