驗證視圖MAC失敗 Validation of ViewState MAC Failed

來源:互聯網
上載者:User
驗證視圖MAC失敗 Validation of ViewState MAC Failed

今天在調試Atlas時遇到錯誤:

驗證視圖MAC失敗。如果此引用程式由網路場或群集承載,請確保<machineKey>配置指定了相同的 validationKey 和驗證演算法。不能在群集中使用 AutoGenerate

發生錯誤的環境:

ASP.NET 2.0,使用Atlas的UpdatePanel,在UpdatePanel中動態載入使用者控制項,以達到動態更新頁面的效果。其中有一個使用者控制項中使用了GridView。當動態切換頁面時,出現上述錯誤。

問題分析:

經過一番搜尋,找到以下的文章:

http://aspadvice.com/blogs/joteke/archive/2006/02/02/15011.aspx

http://forums.asp.net/1173230/ShowPost.aspx

分析後找到了問題的根源。首先,文章中提到,如果用GridView,並且指定了DataKeyNames屬性,則出於安全的理由(因為DataKeyNames指定的欄位代表資料的主鍵,且該主索引值需要儲存在檢視狀態中發送到用戶端,使用者如果篡改主索引值,會導致安全問題),GridView會要求加密檢視狀態。為此會自動在頁面表單</forms>之前添加一個<input type="hidden" name="__VIEWSTATEENCRYPTED" id="__VIEWSTATEENCRYPTED" value="" /> 。

然而,Atlas的UpdatePanel要求放置在<form></form>內部,也就是</form>之前。這就意味著添加的隱藏input控制項沒有被放置在UpdatePanel內,而是放置在UpdatePanel和</form>之間。

當UpdatePanel更新時,UpdatePanel內部的控制項被提交到伺服器進行處理(Patrial Rendering),而整個頁面並沒有被提交。也就是說隱藏的input控制項沒有隨著一起提交。因此伺服器並不知道提交的ViewState被加密了,從而導致MAC驗證錯誤。

解決方案:

通過在Web.config裡邊添加

<pages enableEventValidation="false" viewStateEncryptionMode ="Never" />

可以解決該問題。

ASP.NET 2.0 and "Validation of ViewState Mac failed" exception

If you get this Exception

[HttpException (0x80004005): 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.]

and

  • you know *for sure* that you aren't using a web farm
  • it seems that it appears when using built-in databound controls such as GridView, DetailsView or FormView which utilize DataKeyNames.
  • it appears if you have a large page which loads slowly for any reason

If following preconditions are true and you click a postbacking control/link while the Page hasn't loaded completely, you might get the "Validation of ViewState MAC failed"  exception. In this case be sure to check following post on ASP.NET Forums where this has been discussed quite thoroughly : http://forums.asp.net/1173230/ShowPost.aspx

It appears because GridView using DataKeyNames requires ViewState to be encrypted. And when ViewState is encrypted, Page adds  <input type="hidden" name="__VIEWSTATEENCRYPTED" id="__VIEWSTATEENCRYPTED" value="" /> field just before closing of the <form> tag. But this hidden field might not bet yet rendered to the browser with long-running pages, and if you make a postback before it "gets down", browser initiates postback without this field (in form post collection)

End result is that if this field is omitted on postback, Page doesn't "know" that viewstate is encrypted and causes the prementioned Exception. E.g Page expects to be fully-loaded before you can make a postback. And by the way similar problem is with event validation since __EVENTVALIDATION field is also rendered on the end of the form.

A way to overcome the problem is to set in web.config pages enableEventValidation="false" viewStateEncryptionMode ="Never" />Just note the security implications of these!
在預設狀況ASP.NET會隨機建立manchineKey當作驗證碼,
<configuration>
<system.web >
<machineKey validationKey = "AutoGenerate,IsolateApps"
decryptionKey = "AutoGenerate,IsolateApps" validation = "SHA1"/>
</system.web>
</configuration
若你有兩台Web Server,當另一台要驗證ViewState時,
validationKey或decryptionKey必須是相同的,所以必須自行產生validationKey後,
才能以相同的驗證碼來處理ViewState甚至cookie等。

產生驗證碼的方法如下:

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();
}

產生後即可在每台Web Server網站的Web.Config加上<machineKey>即可,如下
<configuration>
<system.web>
<machineKey validationKey="3FF1E929BC0534950B0920A7B59FA698BD02DFE8"
decryptionKey="280450BB36319B474C996B506A95AEDF9B51211B1D2B7A77"
decryption="3DES" validation="SHA1"/>
</system.web>
</configuration>

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.