Asp.net对viewstate MAC的验证失败

Arb*_*lac 31 asp.net viewstate machinekey

我在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.
Run Code Online (Sandbox Code Playgroud)

当页面刷新时,没问题.我怎样才能解决这个问题?

mBo*_*ros 23

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

<machineKey validationKey="JFDSGOIEURTJKTREKOIRUWTKLRJTKUROIUFLKSIOSUGOIFDS..." decryptionKey="KAJDFOIAUOILKER534095U43098435H43OI5098479854" validation="SHA1" />
Run Code Online (Sandbox Code Playgroud)

把它放在<system.web>标签下面.

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


小智 18

我有这个问题,对我而言,答案与这个问题的其他答案不同.

我有很多客户的应用程序.我在application_error中捕获了所有错误,global.asax并向我发送了一封包含错误详细信息的电子邮件.在我发布了我的应用程序的新版本后,我开始收到很多viewstate MAC验证错误消息.

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

我很抱歉我的英语,我知道我的案子非常具体,但是如果它可以帮助别人节省一天,我认为这是一件好事.


Ton*_* L. 14

微软表示永远不要使用密钥生成器网站.

和其他人一样,我把它添加到我的web.config中.

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

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

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

在此输入图像描述

  1. 双击"机器密钥"图标以获取此屏幕:

在此输入图像描述

  1. 点击我在上图中列出的右侧的"生成密钥"链接.

笔记:

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

  • 我发现这种方法远胜于Microsoft建议的Powershell方法(保持简单),并且比那些生成密钥的网页更具推力。 (2认同)

TsT*_*ime 8

这个解决方案在ASP.NET 4.5中使用Web Forms站点.

  1. 使用以下站点生成计算机密钥:http://www.blackbeltcoder.com/Resources/MachineKey.aspx
  2. 复制整机密钥代码.
  3. 转到您的Web.Config文件.
  4. 将机器密钥粘贴到以下代码部分:

    <configuration>

    <system.web>

    <machineKey ... />
    
    Run Code Online (Sandbox Code Playgroud)

    </system.web>

    </configuration>

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


小智 8

亲爱的大家,对于上面的答案,当 web.config 值为

<httpCookies httpOnlyCookies="true" requireSSL="true"/>
Run Code Online (Sandbox Code Playgroud)

并且链接是 http 而不是 https

  • @eidylon 对我来说它是相关的,通过相同的错误消息来到这里,这个答案解决了我的问题。 (2认同)

Zly*_*Zly 5

在多服务器环境中,当会话过期并且应用程序的另一个实例使用相同的会话 ID 和计算机密钥但位于不同的服务器上时,可能会发生此错误。首先,每个服务器都会生成自己的机器密钥,该密钥随后与应用程序的单个实例相关联。当会话过期并且当前服务器繁忙时,应用程序将通过负载均衡器重定向到更容易操作的服务器。就我而言,我从多个服务器运行同一个应用程序,错误消息:

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

在 web.config 中定义机器码可以解决问题。但是,请不要使用可能已损坏的第 3 方站点来生成代码,而是从命令 shell 运行此命令:基于 microsoft 解决方案 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)
  }
}
Run Code Online (Sandbox Code Playgroud)

然后:

对于 ASP.NET 4.0

Generate-MachineKey
Run Code Online (Sandbox Code Playgroud)

您的密钥将如下所示:<machineKey decryption="AES" decryptionKey="..." validation="HMACSHA256" validationKey="..." />

对于 ASP.NET 2.0 和 3.5

Generate-MachineKey -validation sha1
Run Code Online (Sandbox Code Playgroud)

您的密钥将如下所示:<machineKey decryption="AES" decryptionKey="..." validation="SHA1" validationKey="..." />