视图状态 MAC 的 Asp.net 验证失败

Posted

技术标签:

【中文标题】视图状态 MAC 的 Asp.net 验证失败【英文标题】:Asp.net Validation of viewstate MAC failed 【发布时间】:2011-08-16 00:03:13 【问题描述】:

我在 asp.net 网站上的某些时候收到以下错误。

 Sys.WebForms.PageRequestManagerServerErrorException: 
 Validation of viewstate MAC failed. 
 If this application is hosted by a Web Farm or cluster,
 ensure that <machineKey> configuration specifies the 
 same validationKey and validation algorithm. 
 AutoGenerate cannot be used in a cluster.

当页面刷新时,没有问题。我该如何解决这个问题?

【问题讨论】:

需要更多信息。这是在您的单一开发人员机器上吗?生产服务器?是否有多个生产服务器(即网络场)? 我的开发团队遇到了同样的错误。有些计算机会出现此错误,而有些则不会。任何人都可以提供答案吗? (发布的两个都不能解决我的问题) 我在 MSDN (blogs.msdn.com/b/webtopics/archive/2009/05/13/…) 上看到了这篇文章,你有代码可以重现。提供的解决方案(去掉表单的 action 属性)不好(因为我的表单无处可去) 【参考方案1】:

如果您使用网络场并在多台计算机上运行相同的应用程序,则需要在 machine.config 文件中明确定义机器密钥:

<machineKey validationKey="JFDSGOIEURTJKTREKOIRUWTKLRJTKUROIUFLKSiosUGOIFDS..." decryptionKey="KAJDFOIAUOILKER534095U43098435H43OI5098479854" validation="SHA1" />

把它放在&lt;system.web&gt;标签下。

无法使用机器代码的 AutoGenerate。要生成您自己的 machineKey,请参阅此 powershell 脚本: https://support.microsoft.com/en-us/kb/2915218#bookmark-appendixa

【讨论】:

我的 web.config 中有这一行,但仍然出现此错误。 @TonyDong 它应该进入 Windows 文件夹(Microsoft.NET 子文件夹中的某个位置)中的 machine.config 文件。【参考方案2】:

微软告诉never use a key generator web site。

和这里的其他人一样,我将此添加到我的web.config

<System.Web>
    <machineKey decryptionKey="ABC123...SUPERLONGKEY...5432JFEI242" 
                validationKey="XYZ234...SUPERLONGVALIDATIONKEY...FDA" 
                validation="SHA1" />
</system.web>

但是,我使用 IIS 作为我的 machineKey 生成器,如下所示:

    打开 IIS 并选择一个网站以获取此屏幕:

    双击机器钥匙图标进入此屏幕:

    单击我在上图中概述的右侧的“生成密钥”链接。

注意事项:

如果您选择“为每个应用程序生成唯一密钥” 复选框,“,IsolateApps”将添加到您的密钥的末尾。我有 删除这些以使应用程序正常工作。显然,他们不是一部分 的关键。 SHA1 是 IIS 选择的默认加密方法,如果您更改它,请不要忘记更改 web.config 中 machineKey 的验证属性。但是,加密方法和算法会不断发展,因此请随时编辑 这篇文章带有更新的首选加密方法或提及它 在笔记中,我会更新。

【讨论】:

我发现这种方法比 microsoft 建议的 powershell 方法要好得多(保持简单),并且比那些自动生成密钥的网页更有价值。【参考方案3】:

我遇到了这个问题,对我来说,答案与这个问题的其他答案不同。

我有一个有很多客户的应用程序。我在global.asax 的 application_error 中发现了所有错误,然后我给自己发送了一封包含错误详细信息的电子邮件。在我发布了我的应用程序的新版本后,我开始收到很多 Validation of viewstate MAC failed 错误消息。

经过一天的搜索,我意识到我的应用中有一个计时器,它每分钟刷新一个更新面板。因此,当我发布了我的应用程序的新版本时,一些客户在我的网站上打开了她的电脑。每次计时器刷新时我都会收到一条错误消息,因为实际的视图状态与新的不匹配。在所有客户关闭网站或刷新浏览器以获取新版本之前,我都会收到此消息。

对不起我的英语,我知道我的情况很具体,但是如果它可以帮助某人节省一天,我认为这是一件好事。

【讨论】:

【参考方案4】:

此解决方案在 ASP.NET 4.5 中使用 Web 窗体站点为我工作。

    使用以下站点生成机器密钥:http://www.blackbeltcoder.com/Resources/MachineKey.aspx 复制完整的机器密钥代码。 转到您的 Web.Config 文件。 将机器密钥粘贴到以下代码部分:
    <configuration>
      <system.web>
        <machineKey ... />
      </system.web>
    </configuration> 

您应该不会再看到 viewstate Mac failed 错误。同一应用程序池中的每个网站都应该有一个单独的机器密钥,否则此错误将继续出现。

【讨论】:

我收到这个错误:It is an error to use a section registered as allowDefinition='MachineToApplication' beyond application level. This error can be caused by a virtual directory not being configured as an application in IIS.Idk 这是什么意思。 您在使用 asp.net 上的 Web 表单站点吗?【参考方案5】:

尊敬的所有人,请注意上面的答案 有案例给出这个错误 当 web.config 值为

<httpCookies httpOnlyCookies="true" requireSSL="true"/>

链接是http而不是https

【讨论】:

a) 这是另一个问题,不是答案 b) 这与原始 Q 无关 @eidylon 对我来说是相关的,通过相同的错误消息来到这里,这个答案解决了我的问题。 这是原因之一,您不会在 Microsoft 帮助链接中找到此内容。【参考方案6】:

在多服务器环境中,当会话过期并且应用程序的另一个实例使用相同的会话 ID 和机器密钥但在不同的服务器上时,可能会发生此错误。首先,每台服务器都会产生自己的机器密钥,然后将其与应用程序的单个实例相关联。当会话到期并且当前服务器很忙时,应用程序会通过负载平衡器重定向到更可操作的服务器。在我的情况下,我从多个服务器运行相同的应用程序,错误消息:

视图状态 MAC 验证失败。如果此应用程序由 Web Farm 或集群,确保配置指定 相同的validationKey和验证算法

在web.config下定义机器码可以解决问题。 但不要使用第三方站点来生成可能已损坏的代码,请从您的命令 shell 运行它: 基于微软解决方案1a,https://support.microsoft.com/en-us/kb/2915218#AppendixA

# Generates a <machineKey> element that can be copied + pasted into a Web.config file.
function Generate-MachineKey 
  [CmdletBinding()]
  param (
    [ValidateSet("AES", "DES", "3DES")]
    [string]$decryptionAlgorithm = 'AES',
    [ValidateSet("MD5", "SHA1", "HMACSHA256", "HMACSHA384", "HMACSHA512")]
    [string]$validationAlgorithm = 'HMACSHA256'
  )
  process 
    function BinaryToHex 
        [CmdLetBinding()]
        param($bytes)
        process 
            $builder = new-object System.Text.StringBuilder
            foreach ($b in $bytes) 
              $builder = $builder.AppendFormat([System.Globalization.CultureInfo]::InvariantCulture, "0:X2", $b)
            
            $builder
        
    
    switch ($decryptionAlgorithm) 
      "AES"  $decryptionObject = new-object System.Security.Cryptography.AesCryptoServiceProvider 
      "DES"  $decryptionObject = new-object System.Security.Cryptography.DESCryptoServiceProvider 
      "3DES"  $decryptionObject = new-object System.Security.Cryptography.TripleDESCryptoServiceProvider 
    
    $decryptionObject.GenerateKey()
    $decryptionKey = BinaryToHex($decryptionObject.Key)
    $decryptionObject.Dispose()
    switch ($validationAlgorithm) 
      "MD5"  $validationObject = new-object System.Security.Cryptography.HMACMD5 
      "SHA1"  $validationObject = new-object System.Security.Cryptography.HMACSHA1 
      "HMACSHA256"  $validationObject = new-object System.Security.Cryptography.HMACSHA256 
      "HMACSHA385"  $validationObject = new-object System.Security.Cryptography.HMACSHA384 
      "HMACSHA512"  $validationObject = new-object System.Security.Cryptography.HMACSHA512 
    
    $validationKey = BinaryToHex($validationObject.Key)
    $validationObject.Dispose()
    [string]::Format([System.Globalization.CultureInfo]::InvariantCulture,
      "<machineKey decryption=`"0`" decryptionKey=`"1`" validation=`"2`" validationKey=`"3`" />",
      $decryptionAlgorithm.ToUpperInvariant(), $decryptionKey,
      $validationAlgorithm.ToUpperInvariant(), $validationKey)
  

然后:

对于 ASP.NET 4.0

Generate-MachineKey

您的密钥将如下所示:&lt;machineKey decryption="AES" decryptionKey="..." validation="HMACSHA256" validationKey="..." /&gt;

对于 ASP.NET 2.0 和 3.5

Generate-MachineKey -validation sha1

您的密钥将如下所示:&lt;machineKey decryption="AES" decryptionKey="..." validation="SHA1" validationKey="..." /&gt;

【讨论】:

您在托管网站的服务器上执行此操作?我有一个共享的托管计划。我的网站可以被不同位置/网络上的不同机器访问/ 是的,在您的 web.config 中的 Web 应用服务器上 Tks。我已经设法用我的托管公司提供的服务器机器密钥更新了 web.config。【参考方案7】:

我的问题是这段 javascript 代码

$('input').each(function(ele, indx)
    this.value = this.value.toUpperCase();
);

原来它弄乱了 viewstate 隐藏字段,所以我把它改成了下面的代码,它工作了

$('input:visible').each(function(ele, indx)
    this.value = this.value.toUpperCase();
);

【讨论】:

【参考方案8】:

什么对我有用

    在网上搜索“MachineKey generator”

    转到找到的站点之一并生成机器密钥,它看起来像...(数字更大) ...机钥匙 验证密钥="0EF6C03C11FC...63EAE6A00F0B6B35DD4B" 解密密钥="2F5E2FD80991C629...3ACA674CD3B5F068" 验证="SHA1" 解密="AES" />

    复制并粘贴到 web.config 文件中的 &lt;system.web&gt; 部分。

如果你想走我做过的路……


https://support.microsoft.com/en-us/kb/2915218#AppendixA 解决视图状态消息身份验证代码 (MAC) 错误 解决方案 3b:使用显式 &lt;machineKey&gt; 通过向应用程序的 Web.config 文件添加显式 &lt;machineKey&gt; 元素,开发人员告诉 ASP.NET 不要使用自动生成的加密密钥。有关如何生成 &lt;machineKey&gt; 元素的说明,请参阅附录 A。


http://blogs.msdn.com/b/amb/archive/2012/07/31/easiest-way-to-generate-machinekey.aspx 生成 MachineKey 的最简单方法 - Ahmet Mithat Bostanci - 2012 年 7 月 31 日 您可以在 Bing 中搜索“MachineKey generator”并使用在线服务。老实说……


http://www.blackbeltcoder.com/Resources/MachineKey.aspx

【讨论】:

您提供的 MS 支持链接强烈反对在线 MachineKey Generators support.microsoft.com/en-us/kb/2915218#AppendixA【参考方案9】:

此错误消息通常在您将网站发布到服务器后显示。

主要问题在于您用于网站的应用程序池。

在与您的网站相关的应用程序池的“常规”部分下,将您的网站配置为使用正确的 .NET Framework 版本(即 v4.0)。

在 Process Model 下,将 Identity 值设置为 Network Service。

关闭对话框并右键单击您的网站,然后从内容菜单的管理网站选项中选择高级设置...。在对话框中的“常规”部分下,确保您选择了要使用的应用程序池的正确名称。

您的网站现在应该可以正常运行了。

希望这可以帮助您克服这个错误。

【讨论】:

虽然这些是有用的配置技巧,但告诉 TC“您的网站现在应该可以正常运行”是一种误导。如其他答案所述,真正的答案确实在 machineKey 中。 将身份从 ApplicationPoolIdentity 更改为 NetworkService 为 IIS 提供了超出其需要的权限。这再次降低了解决问题的安全性。请阅读以下内容以获得进一步的解释,iis.net/learn/manage/configuring-security/…【参考方案10】:

视图状态 MAC 验证失败。如果此应用程序由 Web 场或集群托管,请确保 &lt;machineKey&gt; 配置指定相同的验证密钥和验证算法。 AutoGenerate 不能在集群中使用。

答案:

&lt;machineKey  decryptionKey="2CC8E5C3B1812451A707FBAAAEAC9052E05AE1B858993660" validation="HMACSHA256" decryption="AES" validationKey="CB8860CE588A62A2CF9B0B2F48D2C8C31A6A40F0517268CEBCA431A3177B08FC53D818B82DEDCF015A71A0C4B817EA8FDCA2B3BDD091D89F2EDDFB3C06C0CB32" /&gt;

【讨论】:

【参考方案11】:

我遇到了同样的问题,这是由于页面上启用了排序的 Gridview(从 vb 代码生成)。禁用排序解决了我的问题。使用 SQL 数据源创建的网格视图没有这个问题。

【讨论】:

这很奇怪。可能启用排序需要将数据密钥包含在视图状态中,并且 asp.net 对其进行加密。因此,您会收到验证错误。【参考方案12】:

我不确定这是怎么发生的,但我开始在我的内部提交表单页面中收到此错误。因此,当我提交某些内容时,我会收到此错误。但问题是这个网站几乎可以运行 5-6 年。我不记得我做了什么重要的改变。

没有一个解决方案对我有用。

我已经使用 Microsoft 脚本设置了机器密钥并复制到我的 web.config 中

我已经执行了 asp.net regiis 脚本。

aspnet_regiis -ga "IIS APPPOOL\My App Pool"

还尝试将此代码添加到页面中:

enableViewStateMac="false"

还是没有运气。

还有什么办法可以解决这个问题吗?

更新:

最后我解决了这个问题。 我已将我的 angular 4 组件集成到我的 asp.net 网站中。 所以我在我的母版页中添加了基本 href。所以我删除了那个代码,它现在可以正常工作了。

<base href="/" />

【讨论】:

对于其他想要尝试的人 enableViewStateMac="false" 我认为它已被弃用:blogs.msdn.microsoft.com/webdev/2014/09/09/… 引用:“所有版本的 ASP.NET 运行时 1.1 – 4.5.2 现在禁止设置 和 。”【参考方案13】:

还有另一种情况发生在我的客户身上。由于班次变化和用户需要使用不同的用户登录,这种情况通常会在特定时间发生。 这是防伪系统通过生成此错误来保护系统的场景:

1- 一旦关闭/打开您的浏览器。 2- 访问您的网站并使用“用户 A”登录 3- 在浏览器中打开新标签并输入相同的地址站点。 (无需任何身份验证即可查看您的网站首页) 4- 从您的站点注销并在第二个选项卡中与另一个用户(用户 B)登录。 5- 现在返回到您由“用户 A”登录的第一个选项卡。您仍然可以看到该页面,但此选项卡中的任何操作都会导致错误。 因为您的 cookie 已由“用户 B”更新,而您正试图发送无效用户的请求。 (用户 A)

【讨论】:

【参考方案14】:
<system.web>
<pages validateRequest="false" enableEventValidation="false" viewStateEncryptionMode ="Never" />
</system.web>

【讨论】:

一些解释和适当的格式会很好【参考方案15】:

我在 IIS 上托管的网站上遇到了类似的问题。这个问题一般是因为 IIS 应用程序池设置。由于应用程序池在一段时间后回收,这对我来说是个问题。

以下步骤可帮助我解决问题:

    在 IIS 上打开您网站的应用程序池。 转到右侧窗格中的高级设置。 向下滚动到流程模型 将 Idle Time-out 分钟更改为 20 分钟或您不想回收应用程序池的分钟数。

然后再试一次。它会解决你的问题。

【讨论】:

【参考方案16】:

我在我们的项目中遇到了同样的问题。这个Microsoft support web page 帮助我找到了原因。 this solution 帮助解决了这个问题。

在我的情况下,问题在于 ViewStateUserKey,因为 Page.ViewStateUserKey 属性的值不正确 (Caused 4 in here)。如here 中所述,删除 localhost 证书并通过修复 IIS Express 重新创建它们修复了该问题。

【讨论】:

【参考方案17】:

这对我有用

只需添加它: 之间 system.web 部分

【讨论】:

以上是关于视图状态 MAC 的 Asp.net 验证失败的主要内容,如果未能解决你的问题,请参考以下文章

Viewstate MAC 验证失败 ASP.Net 2.0 SP2

设置 ViewStateUserKey 给我一个“视图状态 MAC 验证失败”错误

ASP.NET 应用程序每隔几分钟就会损坏一次视图状态

ASP.NET MVC 页面验证失败(值无效。)

form submit时将__VIEWSTATE和__VIEWSTATEGENERATOR一起post到另外的页面,出现验证视图状态 MAC 失败。

ASP .NET Core 5 Razor Pages:如何正确使用局部视图并验证其模型状态?