即使在localhost中也无法解密防伪令牌?

时间:2014-07-05 22:28:20

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

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

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

我使用了这台机器:

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

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

好吧,可能错误是由多个@html.antiforgerytoken引起的。好吧,我确实有两个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 Vesion:4.5

3 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:1)

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

如果您使用的是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证书签署了我们的身份验证令牌,因此我们避免共享机器密钥。

P.S。发布web.config可能有助于诊断此问题。

答案 2 :(得分:1)

确保您的项目启用了SSL。

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