将 Machine Key 添加到负载平衡环境中的 machine.config 中,以支持多个版本的 .net framework

将 Machine Key 添加到负载平衡环境中的 machine.config 中,以支持多个版本的 .net framework

我在 F5 负载均衡器后面有两台 Web 服务器。每台 Web 服务器都有相同的应用程序。在将负载均衡器的配置从源地址持久性更改为最少连接之前,没有出现任何问题。

现在在某些应用程序中我收到此错误

‘/’应用程序中的服务器错误。

视图状态 MAC 验证失败。如果此应用程序由 Web Farm 或群集托管,请确保配置指定相同的验证密钥和验证算法。AutoGenerate 不能在群集中使用。描述:执行当前 Web 请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其在代码中起源位置的更多信息。

异常详细信息:System.Web.HttpException:视图状态 MAC 验证失败。如果此应用程序由 Web Farm 或群集托管,请确保配置指定相同的 validationKey 和验证算法。AutoGenerate 不能在群集中使用。

源错误:

生成此未处理异常的源代码仅在调试模式下编译时才会显示。要启用此功能,请按照以下步骤之一操作,然后请求 URL:

  1. 在产生错误的文件顶部添加“Debug=true”指令。例如:

或者:

2)将以下部分添加到应用程序的配置文件中:

请注意,第二种技术将导致给定应用程序中的所有文件都以调试模式进行编译。第一种技术将只导致特定文件以调试模式进行编译。

重要提示:在调试模式下运行应用程序确实会产生内存/性能开销。在将应用程序部署到生产场景之前,应确保已禁用调试。

如何将机器密钥添加到 machine.config 文件?我应该在 IIS 中的服务器级别还是在每个站点的网站/应用程序级别执行此操作?两个 Web 服务器上的验证和解密密钥是否必须相同,还是不同?对于 .net 的每个 machine.config 版本,它们是否应该不同?

我找不到有关这种情况的任何文档。

答案1

如果您只需要将其用于您的网站,则可以将其添加到网站的 web.config 中。如果有多个网站/应用程序需要使用相同的 machineKey 进行加密/解密,那么您将使用机器范围的配置文件。

是的,它们在场中的所有服务器上都应该相同,并且您应该对每个.NET 文件夹的 machine.config 执行此操作(.NET 2.0 + 4.0 和 x86 + x64,因此您可能要更新四个文件)。

以下是一些可用于生成密钥的示例代码:

/// <summary>
/// http://msdn.microsoft.com/en-us/library/w8h3skw9.aspx
/// </summary>
public static string CreateMachineKey(int characterLength)
{
    /*
     * decryptionKey:
     * DES: 64 bits (16 hexadecimal characters)
     * 3DES:192 bits (48 hexadecimal characters)
     * AES: 128 bits (32 characters), 192 bits (48 characters), or 256 bits (64 characters)
     * 
       validationKey:
        AES requires a 256-bit key (64 hexadecimal characters).
        MD5 requires a 128-bit key (32 hexadecimal characters).
        SHA1 requires a 160-bit key (40 hexadecimal characters).
        3DES requires a 192-bit key (48 hexadecimal characters).
        HMACSHA256 requires a 256-bit key (64 hexadecimal characters).
        HMACSHA384 requires a 384-bit key (96 hexadecimal characters).
        HMACSHA512 requires a 512-bit key (128 hexadecimal characters).

    */
    byte[] byteArray = new byte[characterLength / 2];
    RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
    rng.GetBytes(byteArray);
    StringBuilder sb = new StringBuilder(characterLength);
    for (int i = 0; i < byteArray.Length; i++)
    {
        sb.Append(string.Format("{0:X2}", byteArray[i]));
    }
    Debug.WriteLine(sb);
    return sb.ToString();
}

以下是 machine.config 的一个示例:

<system.web>
    <machineKey 
    decryption="AES" 
    decryptionKey="D416EFCFEC011CC3A8F0F72A15E7EF725AA39FDBCE3CA361"
    validation="HMACSHA256" 
    validationKey="EF4BFB4B2E1A9AB427430897A13528E4530A231112014E070B246DCA7383EB7F4163D685F590E9B54005F5215AD3BA7CE4EA7D404FE310C543D100D09CC00AE2"/>
</system.web>

文件:

%SYSTEMROOT%\Microsoft.NET\Framework\v4.0.30319\CONFIG\machine.config
%SYSTEMROOT%\Microsoft.NET\Framework64\v4.0.30319\CONFIG\machine.config
%SYSTEMROOT%\Microsoft.NET\Framework\v2.0.5727\CONFIG\machine.config
%SYSTEMROOT%\Microsoft.NET\Framework64\v2.0.5727\CONFIG\machine.config

相关内容