ASP.NET MVC网站登录时出现防伪造令牌无法解密问题求助
ASP.NET MVC 防伪造令牌解密失败问题处理
问题描述
ASP.NET MVC网站部署到Windows Server后,用户登录时服务器抛出错误:
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
<machineKey>configuration specifies explicit encryption and validation keys. AutoGenerate cannot be used in a cluster.
已在视图中添加@Html.AntiForgeryToken(),代码检查未发现明显问题,相关代码及配置如下:
登录Action代码
[HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) { if (!ModelState.IsValid) { ShowErrorMessages("InValid Password"); return View(model); } var email = Business.User.Instance.GetUserEmail(); var result = await SignInManager.PasswordSignInAsync(email, model.Password.Trim(), model.RememberMe, shouldLockout: false); switch (result) { case SignInStatus.Success: return RedirectToLocal(returnUrl); case SignInStatus.LockedOut: return View("Lockout"); case SignInStatus.RequiresVerification: return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe }); case SignInStatus.Failure: default: ShowErrorMessages("Not Valid Password"); return View(model); } }
视图代码
@using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" })) { @Html.AntiForgeryToken() <div class="col-12"> <br /> @Html.LabelFor(m => m.Password, new { @class = "control-label" }) @Html.PasswordFor(m => m.Password, new { @class = "form-control", @maxlength = 30 }) @Html.ValidationMessageFor(m => m.Password, "", new { @class = "text-danger" }) </div> <div class="col-12"> <div class="checkbox"> <br /> @Html.CheckBoxFor(m => m.RememberMe) @Html.LabelFor(m => m.RememberMe) </div> </div> <div class="col-12"> <br /> <input type="submit" value="Log in" class="btn btn-success" /> </div> }
web.config配置
<connectionStrings> <add name="DefaultConnection" connectionString="Data Source=134.154.22.53;Initial Catalog=myDatabaseName" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> <authentication mode="Forms"> <forms loginUrl="~/Account/Login" timeout="533000" slidingExpiration="true"/> </authentication> <compilation debug="true" targetFramework="4.7.2" /> <httpRuntime targetFramework="4.7.2" /> </system.web> <system.webServer> <modules> <remove name="FormsAuthentication" /> </modules> <defaultDocument enabled="true"> <files> <clear /> <add value="index.cshtml"/> </files> </defaultDocument> </system.webServer>
排查与解决步骤
1. 配置固定的machineKey
这是最核心的解决方法。ASP.NET默认自动生成的密钥会在应用池回收、服务器重启后变更,导致令牌无法解密,即使单服务器部署也可能出现该问题。
在web.config的<system.web>节点内添加以下配置:
<machineKey validationKey="生成的128位或256位验证密钥" decryptionKey="生成的128位或256位解密密钥" validation="SHA1" decryption="AES" />
密钥生成方式:
- 可通过.NET代码生成(注意密钥需保密,不要公开):
// 生成256位验证密钥(64字节) string validationKey = System.Web.Security.MachineKey.GenerateKey(64); // 生成256位解密密钥(32字节) string decryptionKey = System.Web.Security.MachineKey.GenerateKey(32);
2. 确认ASP.NET版本一致性
确保服务器上安装的ASP.NET Web Pages版本与开发环境完全一致,版本差异可能导致加密逻辑不兼容。
3. 验证令牌传递完整性
- 查看页面渲染后的HTML,确认存在
__RequestVerificationToken隐藏字段 - 通过浏览器开发者工具检查POST请求,确认该令牌参数已正确携带
4. 清除客户端缓存
用户浏览器缓存的旧令牌可能与当前服务器密钥不匹配,建议清除浏览器Cookie和缓存后重试。
内容的提问来源于stack exchange,提问作者MrMustafa022
相关产品推荐
相关产品推荐

