当页面停留超过20分钟时,视图状态MAC验证失败。

9

如果您在我们服务器上托管的网站中打开一个网页,将其保留20分钟然后提交一个表单,将会出现“验证视图状态MAC失败”错误。

这可能是什么原因呢?

5个回答

13

这可能出现几种情况:

自动生成的机器密钥:

如果您的应用程序池具有默认的20分钟空闲超时时间,并且使用的是自动生成的验证和解密密钥,则每次池启动时都会生成一组新的密钥。这将使浏览器中的加密视图状态失效。您还会发现用于持久票证的表单身份验证票证也将变得无效。

要克服这个问题,请将这些密钥设置为固定值,放在以下位置:

`c:\%systemroot%\microsoft.net\framework\v2.0.50727\CONFIG\machine.config`
你需要在<system.web>部分添加<machineKey>配置元素。这里有一篇非常好的文章,解释了如何做到这一点:

如何在ASP.NET 2.0中配置MachineKey

请滚动到“Web农场部署注意事项”和生成加密随机键。
如果你正在运行一个负载均衡的Web农场,你还需要将每台服务器的machine key设置为完全相同的值。 不正确的form action值(3.5SP1): 还有一种情况(post 3.5SP1),如果你将ASP.NET表单的action属性设置为除正在提交的页面之外的其他值,并且你没有使用跨页postback,那么你将得到这个错误。但是你会立即看到这个错误:

安装.NET 3.5 SP1后视图状态MAC验证失败

时间/长时间运行的页面: 还有一种边缘情况,对于需要很长时间才能呈现的页面,如果页面部分呈现并发生postback:

视图状态MAC验证失败错误

根本原因:这个异常出现是因为使用DataKeyNames的控件需要加密Viewstate。当Viewstate被加密时(默认模式是自动加密如果控件需要,否则不加密),页面在关闭tag之前添加一个隐藏字段。但是,在长时间运行的页面中可能没有呈现此隐藏字段,如果在它之前进行postback,则浏览器会在不带有此字段的情况下启动postback(在表单post收集中)。最终的结果是,如果在postback时省略了此字段,则页面不知道Viewstate已经加密,并导致上述异常。即页面期望在你进行postback之前完全加载。


嗨Kev,感谢您的深入回复。但是,我们已经手动指定了机器密钥。我不认为“action”值对我们有影响,因为我们没有明确设置它,并且我们在ASP.NET 2.0中也遇到了这个问题。此外,由于我们在20分钟内没有执行表单操作,我不认为页面加载时间不足相关。干杯。 - Curtis
@Curt - 嗯,这是一个难题。在这个时间段内,您是否在事件日志中看到任何有趣的信息? - Kev
抱歉,找到了该做这件事的地方!现在会检查一下! - Curtis
嗨Kev,我认为你提供的Web Farm部署注意事项链接有误,它再次指向了Tess的博客? - Ralph Willgoss
1
@RalphWillgoss - 已发现并修复。谢谢。 - Kev
显示剩余2条评论

12

我们花了一些时间才找到了答案,因为我被告知另一个我正在进行比较的IIS7服务器是由同一人以相同的方式设置的。

后来发现,接收此错误的网站所在的服务器使用的是Plesk,而另一个服务器没有使用。

看起来Plesk将应用程序池的空闲超时设置为5分钟,这正是导致此错误的原因。

要更改此设置,请执行以下操作:

  1. 打开IIS
  2. 单击应用程序池节点
  3. 定位您的Web应用程序的应用程序池
  4. 右键单击并选择“高级设置”
  5. 将Idle Time-out(分钟)属性设置为0或将其增加到30分钟以上

1
很高兴你解决了这个问题,我从来没有考虑过空闲超时并且认为它应该是一个合理的值。不管怎样,我的努力是否能得到一票赞成? :) - Kev
哎呀,能不能请您尝试编辑一下您的回答呢?它现在是被锁住了,直到编辑完毕我才能投票。:S - Curtis
@Curt 如果我们将其设置为0,那么是否会增加CSRF的风险? - Rami Zebian

3

对我来说,这解决了问题:

我已经在应用程序池中设置LoadUserProfile = True,使得HKCU注册表子项对应用程序可用。

注意:此方法适用于IIS 7.0及以上版本。


2
我遇到了这个问题,情况是一个单一的Web服务器托管着一个非常基本的ASP.Net应用程序。经过很多努力,我找到了这篇文章,它帮助我理解问题出在工作进程被回收上。
我觉得这很严重,因为这是一个应用程序可能面临的情况,而这样一个核心错误会阻止您正确处理它。据我所见,这是由于处理这些密钥的默认配置将使用machine.config,该文件规定密钥会自动生成并针对每个应用程序进行隔离。我认为在这种情况下,ASP.Net会生成一个临时密钥并将其存储在工作进程级别,当该工作进程消失时,问题就会出现,并且无法处理。
另一种选择是配置机器密钥以解决问题,明显最好将其设置在web.config文件中,而不是整个machine.config文件中,以保持最低的粒度级别。
另一个选项是通过web.config禁用视图状态MAC检查。这将取决于您的应用程序的安全级别以及视图状态被篡改的风险。
最好的选择是在MVC应用程序中避免使用视图状态。

我非常赞同Diego的最佳选项建议。:-) 我讨厌在ASP.Net Webforms页面中出现长的自动生成的HTML元素ID。我发现当HTML元素ID超过50个字符时,JQuery datatables会出现问题。对于Webforms来说,如果我最终使用嵌套重复器和ascx控件页面,我的HTML元素ID通常会有70多个字符,这并不罕见。 - Bryan

0

视图状态 MAC 验证失败。如果此应用程序由 Web Farm 或集群托管,请确保配置指定相同的验证密钥和验证算法。不能在集群中使用 AutoGenerate。 我发现我的母版页标题部分有一个 <base .... 标记,我是在最后一次添加并发布之前添加的。这个标记指定页面上所有链接的默认 URL 和默认目标。这是这次故障的主要原因。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接