Wednesday, June 04, 2008

Application Pool Recycling, Sessions, Machine Key & MAC Validation Errors

I thought I would pass this along to you to save you from the grief…

One of my products sports an assessment engine that requires the assessee to take the assessment in one sitting.  Slated for a future release is a “save as you go” feature that will allow for signing on across multiple sessions to take an assessment.

During testing, there were several people for which English was a second (or even a third) language.  The user spent hours (around 5 to be more precise) taking the assessment, with a dictionary to assist.  After completing the assessment and clicking submit…boom!  Expired session.

So, the first step I took in remedying this problem was to change the session duration to be longer (duh).  This works fine, as long as you remember to change your application pool’s recycle periodicity and settings because recycling has the same effect on session (and, as we will explorer later, machine keys) as a time-out, for obvious reasons.  I soon became weary of this and I decided to explore implementing session management in Microsoft SQL Server.  I was able to get this working very quickly and have subsequently learned much more about session state in ASP.NET by exploring the Session State Provider in some detail.

With session no longer in process, the recycle periodicity and settings have no effect on a user’s ability to continue to interact with the application in the event that IIS recycles the application pool—except for a little performance hit as the app domain and ASP.NET machinery is reload.  Of course, sessions stored in SQL Server still have expiration...

To further bolster the assessment engine’s defenses against session boo-boos, I simply removed session from the assessment page itself.  The other pages, which on average take less than two minutes for a user to traverse, are free to use session but the assessment page uses the page directive EnableSessionState and sets it to false (EnableSessionState="false"). When I need to reload something, which is infrequently on this page, I make the conscious decision to go all the way back to the database instead of relying on session information—a bit paranoid, but the customer’s experience with the assessment pages themselves craft the overall perception of the product more so than any other part of the system.

I figured I was in the clear at this point. 

Second round of testing comes along and BAM, another error pops up that looks like a session related issue—except that session is disabled on the assessment page so what gives?

Here is what is happening:

  1. User signs in and begins taking the assessment.  Session is disabled but the assessment page still employs VIEW STATE
  2. When a application pool is started and a MachineKey is not specified in the application web.config or the server’s web.config, a new MachineKey is automatically generated
  3. If a user is mid-way through taking an assessment and the application pool recycles, a NEW MachineKey is created
  4. When ASP.NET attempts to decrypt the page’s view state using the new MachineKey, it fails, given the old “Validation of Viewstate MAC” error
  5. Error is raised and user’s data is lost

How to handle this?  Well, one way is to include something like the following in application’s web config:

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

Of course, now you have disabled view state encryption and you are no longer using ASP.NET’s request validation scheme, which attempts to shield your application from cross-site scripting and injection threats.  That’s not good.

Another way to handle this is to explicitly configure a MachineKey so the key is available across application pool recycles.   For more information on how to do this, read this.  Go here to see a handy tool that will create the keys automatically and point you to where to include them in the web.config file.

No comments :

Disclaimer

Content on this site is provided "AS IS" with no warranties and confers no rights. Additionally, all content on this site is my own personal opinion and does not represent my employer's view in any way.