即使我在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
答案 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
有人说这是令人困惑的东西,有趣的是,当你创建一个新的MVC项目时,这些东西是开箱即用的,你可能想要追踪你改变了什么以阻止它工作。你需要机器钥匙吗?您是要在服务器场或负载平衡环境中运行它吗?
使用Azure并从分段交换到生产时,我们遇到了同样的问题,因为两台机器都不同。我们最终使用ssl证书签署了我们的身份验证令牌,因此我们避免共享机器密钥。
P.S。发布web.config可能有助于诊断此问题。
答案 2 :(得分:1)
确保您的项目启用了SSL。
即使您使用第三方生成的机器密钥。