{"id":207,"date":"2022-01-07T10:45:11","date_gmt":"2022-01-07T10:45:11","guid":{"rendered":"https:\/\/blog.citrus-lime.com\/crmc\/?p=207"},"modified":"2022-01-07T10:45:11","modified_gmt":"2022-01-07T10:45:11","slug":"how-do-we-fix-the-validation-of-viewstate-mac-failed-error","status":"publish","type":"post","link":"https:\/\/blog.citrus-lime.com\/crmc\/how-do-we-fix-the-validation-of-viewstate-mac-failed-error\/","title":{"rendered":"How do we fix the \u2018Validation of Viewstate MAC failed\u2019 error"},"content":{"rendered":"\n<p>Many ASP.Net Websites use Viewstate to exchange the state of controls on a Page between the Client and the Server, as this works to build web applications that retain the concept of state-fullness or the user\u2019s current page-state between Postbacks into what is the fundamental stateless nature of the web.<\/p>\n\n\n\n<p>Viewstate is then posted back from the client to the server within the body of the page, employing a simple hidden &lt;input&gt; tag to transmit the block of ViewState detail back from the Client to the Server, which the Server then processes to build the Page Appearance and transmit back to the client \u2013 this fits into the traditional Request (from client) and Response (back from the server) view of the world that HTML and Web Frameworks typically operate from.<\/p>\n\n\n\n<p>&lt;input type=&#8221;hidden&#8221; name=&#8221;__VIEWSTATE&#8221; id=&#8221;__VIEWSTATE&#8221; value=&#8221;MyViewState&#8221; \/&gt;<\/p>\n\n\n\n<p>However where we see \u2018MyViewState\u2019 in the above HTML code, this will instead be a long series of Hexdecimal Characters that describe the ViewState being posted from the Client to the Server.&nbsp; For performance and security this block of characters is hash encrypted and hence the real viewstate that ASP.NET uses is translated into this block of (seemingly meaningless) characters \u2013 however this allows ASP.NET to encrypt and decrypt this block into the real Viewstate using a particular Encryption Key.<\/p>\n\n\n\n<p>By default ASP.NET will generate this Encryption Key between the Client and Server upon each request so the communication follows a secure path.<\/p>\n\n\n\n<p>However in a scenario where we are using multiple Web Servers or a Web Farm, this can lead to the following error:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/license.citruslime.com\/cs\/blogs\/crmcs\/image_0E5FED03.png\" alt=\"image\" title=\"image\" \/><\/figure>\n\n\n\n<p>This is due to the way that the View State may be being generated against one Web Server using a particular Encryption Key and then reposted to a different Web Server that is using a separate and different Encryption Key \u2013 leading to an error between the two different Encryption Keys as the key in use at the Client may not match the Key at the Server in this Load Balancing arrangement.<\/p>\n\n\n\n<p>In effect, giving us the following scenario:<\/p>\n\n\n\n<p>1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;User accesses Webpage via&nbsp;<strong>Web Server A<\/strong>&nbsp;\u2013 receives Encryption Key from A<\/p>\n\n\n\n<p>2.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;User posts back Webpage to&nbsp;<strong>Web Server A<\/strong>&nbsp;\u2013 with Web Server A validating the Encryption Key correctly \u2013 no error to the user<\/p>\n\n\n\n<p>3.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;User posts back the Webpage again, and the Load Balancing \/ Web Farm directs the Request to&nbsp;<strong>Web Server B<\/strong>&nbsp;instead \u2013 Web Server B then tries to decrypt the Viewstate using it\u2019s own Encryption Key, finds the difference between Key A and Key B and so throws this error \u2013 user is then presented with the error<\/p>\n\n\n\n<p>The resolution to this is similar to ensuring Session State is consistent when using Load Balancers and Web Farms \u2013 ensuring that a common Encryption Key exists between both Servers A and B, giving us a single key that both A and B use to manage Viewstate to make which Server the User is requesting from irrelevant.<\/p>\n\n\n\n<p><strong>How do we do this?<\/strong><\/p>\n\n\n\n<p>To put this common key in place, we need to run through two steps:<\/p>\n\n\n\n<p>1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Generate the Key \u2013 we access Powershell on the selected Server and run the following command:<\/p>\n\n\n\n<p><strong>Generate-MachineKey<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; This will generate a new Encryption Key in the form that can be used in our Web Application.<\/p>\n\n\n\n<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;machineKey decryption=&#8221;AES&#8221; decryptionKey=&#8221;ABC&#8221; validation=&#8221;SHA1&#8243; validationKey=&#8221;DEF&#8221; \/&gt;<\/strong><\/p>\n\n\n\n<p>2.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Insert this key into our Web Application \u2013 we then need to access the Web.Config on each of our Load Balanced Web Servers and add the &lt;machineKey&gt; tag into the configuration under the &lt;system.web&gt; section:<\/p>\n\n\n\n<p><strong>&lt;configuration&gt;<\/strong><\/p>\n\n\n\n<p><strong>&lt;system.web&gt;<\/strong><\/p>\n\n\n\n<p><strong>&lt;machineKey decryption=&#8221;AES&#8221; decryptionKey=&#8221;ABC&#8221; validation=&#8221;SHA1&#8243; validationKey=&#8221;DEF&#8221; \/&gt;<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The key here being to ensure that each Server is using the same \u2018decryptionKey\u2019 and \u2018encryptionKey\u2019 as generated by the Powershell.<\/p>\n\n\n\n<p>With these two steps in place, the Web Servers should share the same Encryption Key for Viewstate and so this error should no longer occur.<\/p>\n\n\n\n<p><strong>Further Reading<\/strong><\/p>\n\n\n\n<p>This encryption of ViewState is a common part of the ASP.Net Framework and so have many articles and useful reading across the web, particularly from Microsoft and MSDN.&nbsp; The links below give a more detailed set of information on this topic.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><strong>Resolving View State Message Authentication Code (MAC) errors<\/strong><\/p><p><a><strong>https:\/\/support.microsoft.com\/en-us\/kb\/2915218#bookmark-appendixa<\/strong><\/a><strong><\/strong><\/p><\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><strong>Machine Key Element in ASP.NET<\/strong><\/p><p><a><strong>https:\/\/msdn.microsoft.com\/library\/w8h3skw9(v=vs.100).aspx<\/strong><\/a><strong><\/strong><\/p><\/blockquote>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><strong>Generating your Machine Key from IIS 7<\/strong><\/p><p><a><strong>https:\/\/blogs.msdn.com\/b\/vijaysk\/archive\/2009\/05\/13\/iis-7-tip-10-you-can-generate-machine-keys-from-the-iis-manager.aspx<\/strong><\/a><\/p><\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>Many ASP.Net Websites use Viewstate to exchange the state of controls on a Page between the Client and the Server, as this works to build web applications that retain the concept of state-fullness or the user\u2019s current page-state between Postbacks into what is the fundamental stateless nature of the web. Viewstate is then posted back<\/p>\n","protected":false},"author":43,"featured_media":29,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_price":"","_stock":"","_tribe_ticket_header":"","_tribe_default_ticket_provider":"","_tribe_ticket_capacity":"0","_ticket_start_date":"","_ticket_end_date":"","_tribe_ticket_show_description":"","_tribe_ticket_show_not_going":false,"_tribe_ticket_use_global_stock":"","_tribe_ticket_global_stock_level":"","_global_stock_mode":"","_global_stock_cap":"","_tribe_rsvp_for_event":"","_tribe_ticket_going_count":"","_tribe_ticket_not_going_count":"","_tribe_tickets_list":"[]","_tribe_ticket_has_attendee_info_fields":false,"footnotes":""},"categories":[3],"tags":[],"class_list":{"0":"post-207","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-crm"},"featured_image_src":"https:\/\/blog.citrus-lime.com\/crmc\/wp-content\/uploads\/sites\/30\/2021\/11\/Dynamics-365-Marketing-scaled.jpg","author_info":{"display_name":"jadesmith","author_link":"https:\/\/blog.citrus-lime.com\/crmc\/author\/jadesmith\/"},"_links":{"self":[{"href":"https:\/\/blog.citrus-lime.com\/crmc\/wp-json\/wp\/v2\/posts\/207","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.citrus-lime.com\/crmc\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.citrus-lime.com\/crmc\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.citrus-lime.com\/crmc\/wp-json\/wp\/v2\/users\/43"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.citrus-lime.com\/crmc\/wp-json\/wp\/v2\/comments?post=207"}],"version-history":[{"count":1,"href":"https:\/\/blog.citrus-lime.com\/crmc\/wp-json\/wp\/v2\/posts\/207\/revisions"}],"predecessor-version":[{"id":208,"href":"https:\/\/blog.citrus-lime.com\/crmc\/wp-json\/wp\/v2\/posts\/207\/revisions\/208"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.citrus-lime.com\/crmc\/wp-json\/wp\/v2\/media\/29"}],"wp:attachment":[{"href":"https:\/\/blog.citrus-lime.com\/crmc\/wp-json\/wp\/v2\/media?parent=207"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.citrus-lime.com\/crmc\/wp-json\/wp\/v2\/categories?post=207"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.citrus-lime.com\/crmc\/wp-json\/wp\/v2\/tags?post=207"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}