在網上搜尋了好久看了不少關於MAC驗證視圖狀態失敗的解決方法。大部分人都說是在頁裏或web.config里加web
EnableEventValidation="false" EnableViewStateMac="false" ViewStateEncryptionMode="Never" 這些屬性的設算法
置。可是這並不從根本上解決問題,相反這樣作了反而更加不安全。安全
爲了解決問題我繼續收集資料,不經意的發現了一個網頁裏講到一個Blog系統從NET1.1升級到NET2後,以前所生服務器
成的全部cookies將會失效,由於NET2和NET1使用的machineKey不同。哈哈,真是恍然大悟啊!cookie
WEB應用中常常遇到採用集羣或負載均衡交換機等方式實現多服務器共同對外提供服務,分擔壓力。在這樣的環境下網絡
若是Asp.Net程序執行時碰到以下中文錯誤:app
「驗證視圖狀態 MAC 失敗。若是此應用程序由網絡場或羣集承載,請確保 <machineKey> 配置指定了相同的負載均衡
validationKey 和驗證算法。不能在羣集中使用 AutoGenerate。」this
或以下英文錯誤:加密
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驗證是能夠解決問題,但這不是根本的,起碼是犧牲了必定的安全性!