排除防伪标记问题

我有一个表格post,一直给我一个反伪造令牌错误。

这是我的forms:

@using (Html.BeginForm()) { @Html.AntiForgeryToken() @Html.EditorFor(m => m.Email) @Html.EditorFor(m => m.Birthday) <p> <input type="submit" id="Go" value="Go" /> </p> } 

这是我的行动方法:

 [HttpPost] [ValidateAntiForgeryToken] public ActionResult Join(JoinViewModel model) { //a bunch of stuff here but it doesn't matter because it's not making it here } 

这是web.config中的machineKey:

 <system.web> <machineKey validationKey="mykey" decryptionKey="myotherkey" validation="SHA1" decryption="AES" /> </system.web> 

这是我得到的错误:

 A required anti-forgery token was not supplied or was invalid. 

我已经读过,改变HttpContext上的用户将令牌无效,但这不是在这里发生。 我的Join操作上的HttpGet只是返回视图:

 [HttpGet] public ActionResult Join() { return this.View(); } 

所以我不确定发生了什么事。 我已经search了一切,似乎一切都表明,它是machineKey更改(应用程序周期)或用户/会话更改。

还有什么可以进行? 我怎样才能解决这个问题?

我不知道你是否意味着你可以根据需要得到错误信息,或者你在日志中看到错误,但是无论如何,这是一种保证防伪令牌错误的方法。

等一下

  • 确保您已注销,然后input您的login信息
  • 双击loginbutton
  • 你会得到:

提供的防伪标记是用于用户“”,但当前用户是“XXX@yahoo.com”。

(现在我将假设这个确切的错误信息在MVC4中发生了变化,而且这与本质上是相同的信息)。

还有很多人仍然双击一切 – 这是不好的! 刚刚醒来之后我就明白了这一点,所以如何通过testing,我真的不知道。 你甚至不需要双击 – 如果button没有响应,我再次点击时,我自己得到了这个错误。

我刚刚删除了validation属性。 我的网站总是SSL,我不太在意风险。 我只是需要它现在工作。 另一个解决scheme是禁用与JavaScript的button。

这可以在MVC4初始安装模板上复制。

在Adam的帮助下,我得到了添加到我的项目中的MVC源代码,并且能够看到导致相同错误的很多情况。

以下是用于validation防伪造标记的方法:

  public void Validate(HttpContextBase context, string salt) { Debug.Assert(context != null); string fieldName = AntiForgeryData.GetAntiForgeryTokenName(null); string cookieName = AntiForgeryData.GetAntiForgeryTokenName(context.Request.ApplicationPath); HttpCookie cookie = context.Request.Cookies[cookieName]; if (cookie == null || String.IsNullOrEmpty(cookie.Value)) { // error: cookie token is missing throw CreateValidationException(); } AntiForgeryData cookieToken = Serializer.Deserialize(cookie.Value); string formValue = context.Request.Form[fieldName]; if (String.IsNullOrEmpty(formValue)) { // error: form token is missing throw CreateValidationException(); } AntiForgeryData formToken = Serializer.Deserialize(formValue); if (!String.Equals(cookieToken.Value, formToken.Value, StringComparison.Ordinal)) { // error: form token does not match cookie token throw CreateValidationException(); } string currentUsername = AntiForgeryData.GetUsername(context.User); if (!String.Equals(formToken.Username, currentUsername, StringComparison.OrdinalIgnoreCase)) { // error: form token is not valid for this user // (don't care about cookie token) throw CreateValidationException(); } if (!String.Equals(salt ?? String.Empty, formToken.Salt, StringComparison.Ordinal)) { // error: custom validation failed throw CreateValidationException(); } } 

我的问题是,它将身份用户名与表单标记的用户名进行比较的情况。 在我的情况下,我没有设置用户名(一个是空的,另一个是空string)。

虽然我怀疑很多人会遇到这种情况,希望其他人会发现它有用,看到正在检查的基本条件。

您应该防止双重表单提交。 我使用这样的代码来防止这种types的问题:

 $('#loginForm').on('submit',function(e){ var $form = $(this); if (!$form.data('submitted') && $form.valid()) { // mark it so that the next submit can be ignored $form.data('submitted', true); return; } // form is invalid or previously submitted - skip submit e.preventDefault(); }); 

要么

 $('#loginForm').submit(function () { $(this).find(':submit').attr('disabled', 'disabled'); }); 

AntiForgeryToken还会检查您login的用户凭证是否未更改 – 这些还在Cookie中encryption。 您可以通过在global.asax.cs文件中设置AntiForgeryConfig.SuppressIdentityHeuristicChecks = true来closures此function。

我刚刚遇到了一个问题: @Html.AntiForgeryToken()被调用两次,所以Anti-forger标记被搞砸在HTTP Post中。

你在一台服务器或networking农场? 如果单个服务器,请在web.config中注释掉您的machineKey元素,然后再次尝试作为基础起点。 任何改变? 另外 – 你能想到你的cookies会被清除或过期的任何原因 – 他们也需要这个工作正常。

当我不得不将我的应用程序迁移到新机器时,我也遇到了同样的问题。 我不明白为什么这个错误突然performance出来,但是觉得肯定与迁移有关,所以开始通过aspnet_reqsql来调查数据库的注册,当这个被删除的时候,我意识到它必须做的是注册应用程序果然我在类似的地方find了答案。 我也在旅途中发现有两种方法可以解决这个问题。

  1. ASP.NET会自动为每个应用程序生成一个encryption密钥,并将密钥存储在HKCUregistryconfiguration单元中。 当在服务器群中迁移或访问应用程序时,这些密钥不匹配,因此方法之一是将唯一的机器密钥添加到web.config中。 机器密钥可以从IISpipe理控制台生成,并添加到您的web.config部分

    的<machineKey的validationKey = “DEBE0EEF2A779A4CAAC54EA51B9ACCDED506DA2A4BEBA88FA23AD8E7399C4A8B93A006ACC1D7FEAEE56A5571B5AB6D74819CFADB522FEEB101B4D0F97F4E91” decryptionKey = “7B1EF067E9C561EC2F4695578​​295EDD5EC454F0F61DBFDDADC2900B01A53D4” validation= “SHA1” 解密= “AES”/>

  2. 第二种方法是通过使用AspNet_RegIIS的appPool和switch -ga或者使用-i的所有应用程序授予对HKCU工作进程的registry的访问权限

aspnet_regiis -ga“IIS APPPOOL \ app-pool-name”

无论select哪种方法都应该解决这个问题,但是在我看来,未来迁移和服务器更改最可靠的方法将是web.config中的唯一键,记住这会导致应用程序覆盖HKCUregistryconfiguration单元,让你的应用程序运行。

另一个可能的事情来检查是什么导致了我的这个错误:我有两个@Html.AntiForgeryToken()在我的一种forms。

一旦被删除,问题就消失了。

有必要检查表单是否有效,然后禁用提交button。

 <script type="text/javascript"> //prevent double form submission $('form', '#loginForm').submit(function () { if ($(this).valid()) { $(this).find(':submit').attr('disabled', 'disabled'); } }); 

html错误logging器是不正确的行。

你必须检查页面中的所有加载值是否为空。