大部分人都說是在頁里或web.config里加EnableEventValidation="false" EnableViewStateMac="false" ViewStateEncryptionMode="Never" 這些屬性的設置。但是這並不從根本上解決問題,相反這樣做了反而更加不安全。
為了解決問題我繼續收集資料,不經意的發現了一個網頁里講到一個Blog系統從NET1.1升級到NET2后,之前所生成的所有cookies將會失效,因為NET2和NET1使用的machineKey不一樣。哈哈,真是恍然大悟啊!
WEB應用中經常遇到采用集群或負載均衡交換機等方式實現多服務器共同對外提供服務,分擔壓力。在這樣的環境下,如果Asp.Net程序執行時碰到如下中文錯誤:
“驗證視圖狀態 MAC 失敗。如果此應用程序由網絡場或群集承載,請確保 <machineKey> 配置指定了相同的validationKey 和驗證算法。不能在群集中使用 AutoGenerate。”
或如下英文錯誤:
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.
則說明多台WEB服務器上的WEB應用程序沒有使用統一的machineKey導致的。
那么machineKey的作用是什么呢?
按照MSDN的標准說法:“對密鑰進行配置,以便將其用於對 Forms 身份驗證 Cookie 數據和視圖狀態數據進行加密和解密,並將其用於對進程外會話狀態標識進行驗證。”
也就是說Asp.Net的很多加密,都是依賴於machineKey的設置,例如Forms 身份驗證 Cookie、ViewState的加密。默認情況下,Asp.Net的配置是自己動態生成,validationKey和decryptionKey的默認值是AutoGenerate。如果單台服務器當然沒問題,但是如果多台服務器負載均衡,machineKey還采用動態生成的方式,每台服務器上的machinekey值不一致,就導致加密出來的結果也不一致,不能共享驗證和ViewState,所以對於多台服務器負載均衡的情況,一定要在每台站點配置相同的machineKey。
至此真相水落石出,立刻在web.config中添加關於machineKey的配置項,並手動設置其中的密鑰值,這里請注意,不同加密算法對於密鑰的最大字符長度是不同的,在這里能夠使用的有AES,DES,3DES,SHA1,MD5,我只知道DES的密鑰字符長度為16,3DES長度為48,手動設置時密鑰長度必須等於其最大長度,否則會出錯!至於密鑰的16進制值可以隨便輸入。
參考的web.config 中matchineKey配置:
<system.web>
<machineKey validation="3DES" validationKey="319B474B1D2B7A87C996B280450BB36506A95AEDF9B51211"
decryptionKey="280450BB36319B474C996B506A95AEDF9B51211B1D2B7A87" decryption="3DES"/>
</system.web>
好了,問題得已解決!希望廣大朋友遇到MAC驗證視圖狀態失敗的問題的時候,不要馬上把EnableViewStateMac="false"設置成這樣就完事了。先分析什么原因導致了這個錯誤的發生,禁用掉EnableViewStateMac驗證是可以解決問題,但這不是根本的,起碼是犧牲了一定的安全性!
原文:http://blog.csdn.net/liu_zhongjie/article/details/5290365
注意:實際使用時報錯
此時按照提示將validation換成SHA1就OK了