Loosing forms authentication after ASP.NET application recycles
I recently moved my blog to a hosting center (more on that in another post) and hit a few strange issues:
- forms would fail with an Invalid Viewstate error
- forms authentication would be lost after my web application was recycled
I know why it happens (ASP.NET security measures) but not what is causing it.
Let me try to explain better. ASP.NET does it best to make sure the ViewState and forms authentication cannot be hacked by “signing“ sensitive data. The <machineKey> element in Machine.Config decides how the key is generated and which algorithm to use. The computer can generate the key automatically but it is machine specific so the key must be the same on all machines in a web arm. So far, so good. But I only have a single “dedicated“ server so the key should always stay the same and I should not have any problems.
Not so simple. The key is normally set to “AutoGenerate“ in machine.config which usually work but not in my case. The most likely cause is the account used to run the ASP.NET worker process as the key is stored in the registry with access limited to "Network Service":
When the machineKey is set to AutoGenerate, the key information is stored in the HKEY_CURRENT_USER hive for the account running the process. For W2k3 servers, this is the Network Service account. Otherwise, the account is ASP.NET machine account. When the process launches, ASP.NET will use the HKEY_CURRENT_USER registry key if it is available. If this key is not available, the
HKEY_LOCAL_MACHINE key will be used. If neither registry key exists, the process creates the key in the HKEY_LOCAL_MACHINE hive. If these conditions fail, the process creates a brand new set of keys
My worker process was running as “Network Service“ but I didn't have time to dig into the registry security settings so I applied the procedure for configuring machines in a web garden. Luckily the fix is a lot simpler than the explanation:
- Use a machineKey generator to generate the settings for your machine
- Replace your existing <machineKey> element in machine.config with the generated section
This MSDN article explains the dirty details better