排除防伪标记问题
我有一个表格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了答案。 我也在旅途中发现有两种方法可以解决这个问题。
-
ASP.NET会自动为每个应用程序生成一个encryption密钥,并将密钥存储在HKCUregistryconfiguration单元中。 当在服务器群中迁移或访问应用程序时,这些密钥不匹配,因此方法之一是将唯一的机器密钥添加到web.config中。 机器密钥可以从IISpipe理控制台生成,并添加到您的web.config部分
的<machineKey的validationKey = “DEBE0EEF2A779A4CAAC54EA51B9ACCDED506DA2A4BEBA88FA23AD8E7399C4A8B93A006ACC1D7FEAEE56A5571B5AB6D74819CFADB522FEEB101B4D0F97F4E91” decryptionKey = “7B1EF067E9C561EC2F4695578295EDD5EC454F0F61DBFDDADC2900B01A53D4” validation= “SHA1” 解密= “AES”/>
-
第二种方法是通过使用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器是不正确的行。
你必须检查页面中的所有加载值是否为空。