<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>bencoffman.com/blog - viewstate</title>
    <link>http://bencoffman.com/blog/</link>
    <description>News about Tech and a few other things.</description>
    <language>en-us</language>
    <copyright>Ben Coffman</copyright>
    <lastBuildDate>Tue, 21 Jul 2009 17:30:38 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.1.8102.813</generator>
    <managingEditor>coffmanben@gmail.com</managingEditor>
    <webMaster>coffmanben@gmail.com</webMaster>
    <item>
      <trackback:ping>http://bencoffman.com/blog/Trackback.aspx?guid=1b984f21-060d-4549-bdd3-ca061a571ccb</trackback:ping>
      <pingback:server>http://bencoffman.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://bencoffman.com/blog/PermaLink,guid,1b984f21-060d-4549-bdd3-ca061a571ccb.aspx</pingback:target>
      <dc:creator>Ben Coffman</dc:creator>
      <wfw:comment>http://bencoffman.com/blog/CommentView,guid,1b984f21-060d-4549-bdd3-ca061a571ccb.aspx</wfw:comment>
      <wfw:commentRss>http://bencoffman.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=1b984f21-060d-4549-bdd3-ca061a571ccb</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <font size="3">
          <b>
          </b>
        </font>
        <b>Error Readout:</b>
        <br />
        <i>Exception: System.Web.HttpException<br />
Message: Authentication of viewstate failed. 1) If this is a cluster, edit 
<machineKey>
configuration so all servers use the same validationKey and validation algorithm.
AutoGenerate cannot be used in a cluster. 2) Viewstate can only be posted back to
the same page. 3) The viewstate for this page might be corrupted.<br />
Source: System.Web<br />
at System.Web.UI.LosFormatter.Deserialize(String input)<br />
at System.Web.UI.Page.LoadPageStateFromPersistenceMedium()
</machineKey></i>
        <br />
        <br />
        <br />
        <b>Fix:<br /></b>I encountered the above error the other day. Since the server wasn't on a web
farm I was a little confused. The fix I ended up using was updating the web.config
key to<br /><br /><font size="2"><b>requiressl=true</b></font><br /><br /><br /><b>Explanation: </b><br />
The next thing I asked myself was how can that key affect the viewstate. With some
serious investigation into viewstate and best practices I finally made the link of
how our applications viewstate is tied to session state which is tied to SSL when
the session cookies are encrypted manually, a step (encrypting our own session cookies
manually) we did because we are still running asp.net 1.1.<br /><div><br /><i>How to manually encrypt the sessionid in a cookie</i><span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;"><br />
Response.Cookies[<span style="color: rgb(102, 102, 102); background-color: rgb(228, 228, 228); font-family: Courier New; font-size: 11px;">"ASP.NET_SessionId"</span>].Secure</span><br /><br />
Lets dive right into how session state and viewstate work to get a better understanding
of the solution. ASP.NET session state lets you associate a server-side string or
object dictionary containing state data with a particular HTTP client session. A session
is defined as a series of requests issued by the same client within a certain period
of time, and is managed by associating a session ID with each unique client. The ID
is supplied by the client on each request, either in a cookie or as a special fragment
of the request URL.<br />
[<a href="http://msdn.microsoft.com/en-us/magazine/cc163730.aspx">http://msdn.microsoft.com/en-us/magazine/cc163730.aspx</a>]
</div><br />
In .net 1.1 there is a property called "ViewStateUserKey" located in the viewstate,
this key adds user-specific information to the view state. When the request is processed,
ASP.NET extracts the key from the view state and compares it against the <b>ViewStateUserKey</b> of
the running page. If the two match, the request is considered legitimate; otherwise
an exception is thrown. In our application we use the Session.SessionID to set the
property. This is where my problem starts. 
<br /><br />
When a user fills out a form utilizing viewstate to create an account to login to
our system the user establishes a viewstate in their asp.net page. In order to make
the view state slightly more secure we give the viewstateuserkey the same value as
the session ID. The session ID is a much better fit because a session ID is unpredictable,
times out, and varies on a per-user basis<br />
[<a href="http://msdn.microsoft.com/en-us/library/ms972969.aspx">http://msdn.microsoft.com/en-us/library/ms972969.aspx</a>]<br /><br />
Once the user has completely filled out the form, we authenticate them. This is where
my error occurs [See beginning of post]. 
<br /><br /><br />
The error is caused because the session id is now encrypted. It's encrypted because
our security team said, all information stored in cookies is to be secured. Our team
consequently set up a flag in the global.asax file that states if this flag is set
to true it should grab the session id out of each cookie and encrypt it. The reason
we did this by hand is because asp.net 1.1 does not offer secure cookies with one
easy key change in the web.config [NOTE: In asp.net 2.0 all you have to do is have
the requiressl=true and you are done].<br /><br />
Now understanding that our session ID is tied to our viewstateuserkey you can understand
the viewstateuserkey is now invalid because the session ID is a different value, simply
because it's encrypted and the server does not know to decrypt it. [<i>NOTE: The session
ID may still be the same value, it's just encrypted.</i>] Now asp.net states the viewstateuserkey
is invalid and pumps out the error you have seen above. 
<br /><br />
To fix this I simply change requiressl=true in the web.config. How does requrie ssl
affect an encrypted session id within a cookie that I set to encrypt? Well, when requiressl
is not on but you are sending the server a secure cookie value, which we did since
we created our own secure cookies in asp.net 1.1 the server doesn't know to decrypt
the cookie because requiressl is not turned on [<i>apparently you have to send secure
cookies over ssl in asp.net 1.1 and possibly other run times, I didn't know this</i>]
which in turn invalidates the viewstateuserkey because the viewstateuserkey uses the
session ID which is encrypted in the secure cookie. 
<br /><br />
What made this confusing for me is the first part of the form worked without a hitch.
It's when the user authenticates when the error arose. The reason for this being that
the requiressl key is not applicable until authentication happens. If you'll notice
the requiressl key is nested in the authentication element in the web.config file.
Additionally we don't encrypt the cookie until the user is authenticated. Sooo, the
first few postbacks for our page were just collecting information. It wasn't until
we authenticated the user to our system that requiressl actually cared if we had secure
cookies or not. 
<br /><br /><br /><b>Overview</b><br />
Viewstateuserkey is set to the session ID.<br /><br />
Session ID is encrypted and the updated value is set to the viewstateuserkey<br /><br />
requressl being turned on tells the server to decrypt session id in which case allows
the viewstateuserkey to remain valid with the server.<br /><br /><p><br /></p><img width="0" height="0" src="http://bencoffman.com/blog/aggbug.ashx?id=1b984f21-060d-4549-bdd3-ca061a571ccb" /></body>
      <title>1) If this is a cluster, edit &lt;machineKey&gt; configuration so all servers use the same validationKey  ...</title>
      <guid isPermaLink="false">http://bencoffman.com/blog/PermaLink,guid,1b984f21-060d-4549-bdd3-ca061a571ccb.aspx</guid>
      <link>http://bencoffman.com/blog/2009/07/21/1IfThisIsAClusterEditConfigurationSoAllServersUseTheSameValidationKey.aspx</link>
      <pubDate>Tue, 21 Jul 2009 17:30:38 GMT</pubDate>
      <description>&lt;font size="3"&gt;&lt;b&gt;&lt;/b&gt;&lt;/font&gt;&lt;b&gt;Error Readout:&lt;/b&gt;
&lt;br&gt;
&lt;i&gt;Exception: System.Web.HttpException&lt;br&gt;
Message: Authentication of viewstate failed. 1) If this is a cluster, edit 
&lt;machineKey&gt;
configuration so all servers use the same validationKey and validation algorithm.
AutoGenerate cannot be used in a cluster. 2) Viewstate can only be posted back to
the same page. 3) The viewstate for this page might be corrupted.&lt;br&gt;
Source: System.Web&lt;br&gt;
at System.Web.UI.LosFormatter.Deserialize(String input)&lt;br&gt;
at System.Web.UI.Page.LoadPageStateFromPersistenceMedium()
&lt;/i&gt;
&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;b&gt;Fix:&lt;br&gt;
&lt;/b&gt;I encountered the above error the other day. Since the server wasn't on a web
farm I was a little confused. The fix I ended up using was updating the web.config
key to&lt;br&gt;
&lt;br&gt;
&lt;font size="2"&gt;&lt;b&gt;requiressl=true&lt;/b&gt;&lt;/font&gt;
&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;b&gt;Explanation: &lt;/b&gt;
&lt;br&gt;
The next thing I asked myself was how can that key affect the viewstate. With some
serious investigation into viewstate and best practices I finally made the link of
how our applications viewstate is tied to session state which is tied to SSL when
the session cookies are encrypted manually, a step (encrypting our own session cookies
manually) we did because we are still running asp.net 1.1.&lt;br&gt;
&lt;div&gt;
&lt;br&gt;
&lt;i&gt;How to manually encrypt the sessionid in a cookie&lt;/i&gt;&lt;span style="color: Black; background-color: transparent; font-family: Courier New; font-size: 11px;"&gt;
&lt;br&gt;
Response.Cookies[&lt;span style="color: rgb(102, 102, 102); background-color: rgb(228, 228, 228); font-family: Courier New; font-size: 11px;"&gt;"ASP.NET_SessionId"&lt;/span&gt;].Secure&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
Lets dive right into how session state and viewstate work to get a better understanding
of the solution. ASP.NET session state lets you associate a server-side string or
object dictionary containing state data with a particular HTTP client session. A session
is defined as a series of requests issued by the same client within a certain period
of time, and is managed by associating a session ID with each unique client. The ID
is supplied by the client on each request, either in a cookie or as a special fragment
of the request URL.&lt;br&gt;
[&lt;a href="http://msdn.microsoft.com/en-us/magazine/cc163730.aspx"&gt;http://msdn.microsoft.com/en-us/magazine/cc163730.aspx&lt;/a&gt;]
&lt;/div&gt;
&lt;br&gt;
In .net 1.1 there is a property called "ViewStateUserKey" located in the viewstate,
this key adds user-specific information to the view state. When the request is processed,
ASP.NET extracts the key from the view state and compares it against the &lt;b&gt;ViewStateUserKey&lt;/b&gt; of
the running page. If the two match, the request is considered legitimate; otherwise
an exception is thrown. In our application we use the Session.SessionID to set the
property. This is where my problem starts. 
&lt;br&gt;
&lt;br&gt;
When a user fills out a form utilizing viewstate to create an account to login to
our system the user establishes a viewstate in their asp.net page. In order to make
the view state slightly more secure we give the viewstateuserkey the same value as
the session ID. The session ID is a much better fit because a session ID is unpredictable,
times out, and varies on a per-user basis&lt;br&gt;
[&lt;a href="http://msdn.microsoft.com/en-us/library/ms972969.aspx"&gt;http://msdn.microsoft.com/en-us/library/ms972969.aspx&lt;/a&gt;]&lt;br&gt;
&lt;br&gt;
Once the user has completely filled out the form, we authenticate them. This is where
my error occurs [See beginning of post]. 
&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
The error is caused because the session id is now encrypted. It's encrypted because
our security team said, all information stored in cookies is to be secured. Our team
consequently set up a flag in the global.asax file that states if this flag is set
to true it should grab the session id out of each cookie and encrypt it. The reason
we did this by hand is because asp.net 1.1 does not offer secure cookies with one
easy key change in the web.config [NOTE: In asp.net 2.0 all you have to do is have
the requiressl=true and you are done].&lt;br&gt;
&lt;br&gt;
Now understanding that our session ID is tied to our viewstateuserkey you can understand
the viewstateuserkey is now invalid because the session ID is a different value, simply
because it's encrypted and the server does not know to decrypt it. [&lt;i&gt;NOTE: The session
ID may still be the same value, it's just encrypted.&lt;/i&gt;] Now asp.net states the viewstateuserkey
is invalid and pumps out the error you have seen above. 
&lt;br&gt;
&lt;br&gt;
To fix this I simply change requiressl=true in the web.config. How does requrie ssl
affect an encrypted session id within a cookie that I set to encrypt? Well, when requiressl
is not on but you are sending the server a secure cookie value, which we did since
we created our own secure cookies in asp.net 1.1 the server doesn't know to decrypt
the cookie because requiressl is not turned on [&lt;i&gt;apparently you have to send secure
cookies over ssl in asp.net 1.1 and possibly other run times, I didn't know this&lt;/i&gt;]
which in turn invalidates the viewstateuserkey because the viewstateuserkey uses the
session ID which is encrypted in the secure cookie. 
&lt;br&gt;
&lt;br&gt;
What made this confusing for me is the first part of the form worked without a hitch.
It's when the user authenticates when the error arose. The reason for this being that
the requiressl key is not applicable until authentication happens. If you'll notice
the requiressl key is nested in the authentication element in the web.config file.
Additionally we don't encrypt the cookie until the user is authenticated. Sooo, the
first few postbacks for our page were just collecting information. It wasn't until
we authenticated the user to our system that requiressl actually cared if we had secure
cookies or not. 
&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;b&gt;Overview&lt;/b&gt;
&lt;br&gt;
Viewstateuserkey is set to the session ID.&lt;br&gt;
&lt;br&gt;
Session ID is encrypted and the updated value is set to the viewstateuserkey&lt;br&gt;
&lt;br&gt;
requressl being turned on tells the server to decrypt session id in which case allows
the viewstateuserkey to remain valid with the server.&lt;br&gt;
&lt;br&gt;
&lt;p&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://bencoffman.com/blog/aggbug.ashx?id=1b984f21-060d-4549-bdd3-ca061a571ccb" /&gt;</description>
      <comments>http://bencoffman.com/blog/CommentView,guid,1b984f21-060d-4549-bdd3-ca061a571ccb.aspx</comments>
      <category>.Net</category>
      <category>session state</category>
      <category>viewstate</category>
    </item>
  </channel>
</rss>