Posts Tagged ‘Validation of ViewState MAC Failed’

.NET 验证视图MAC失败 Validation of ViewState MAC Failed 的解决方法

星期日, 七月 28th, 2013 56 views

最近给网站服务器做了集群,即用智能DNS做多台服务器的联合,可以保证在一台网站服务器宕机的情况下,网站不会出现无法访问的情况。但问题随着而来,最近经常有客户反映出现Validation of ViewState MAC Failed 错误。
如图


翻译为:
验证视图MAC失败。如果此应用程序由群集承载,请确保配置指定了相同的 validationKey 和验证算法。不能在群集中使用 AutoGenerate。

在微软官方获得了解决方案。错误原因是集群web服务器应当设置相同的validationKey和decryptionKey。
因为.NET 的很多加密,都是依赖于machineKey中的key,默认情况下.NET 会动态生成这个key,但每台服务器上的动态生成的machinekey值是不一致的,单服务器不会出现问题。
而在集群情况下,machinekey不一致的话,不能共享验证和ViewState,因此对于集群.NET,一定要使用相同的machineKey。
因此需要在web.config中手动添加这个machineKey:

1
2
3
4
5
<system.web>
    <machineKey validationKey="24-64位key(如3FF1E929BC0534950B0920A7B59FA698BD02DFE8)"
   decryptionKey="24-64位key(如280450BB36319B474C996B506A95AEDF9B51211B1D2B7A77)"
   decryption="AES" validation="SHA1"/>
</system.web>

上面的validationKey和decryptionKey都可以自己生成,网上已经很多生成方法,这里直接复制过来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
string validationKey = GetKey(30); //20~64均可
string decryptionKey = GetKey(30); //20~64均可

protected string GetKey(int Keylen)
{
    byte[] bytes = new byte[Keylen];
    new RNGCryptoServiceProvider().GetBytes(bytes);
    StringBuilder Builder = new StringBuilder();
    for (int i = 0; i < bytes.Length; i++)
    {
        Builder.Append(string.Format("{0:X2}", bytes[i]));
    }
    return Builder.ToString();
}

另一种处理方法是直接关闭ViewStateMac功能,在页面头部添加配置信息:enableViewStateMac=”false”
<%@ Page Language="C#" enableViewStateMac="false"%>
但涉及到页面提交,form验证,共享session等功能都需要使用到ViewStateMac,所以此方案无异于自杀,因此也被大多数开发者唾弃。

本文仅供参考,到此搁笔,谢谢关注。

BeiTown
2013.07.28