File under: important but hard to find info. Found bits of this in Stefan Schackow excellent book and added some context.
You may know when you are impersonating and you spawn a new thread, the impersonation token will not be copied to this new thread automatically, but the process token will be used. This can lead to subtle security holes, e.g. when your process is running as LOCAL SYSTEM (never do that!!) and is impersonating a least privilege account (e.g. a client) and you spawn a new thread, this new thread will run as LOCAL SYSTEM. This can also happen if you call a STA COM component (e.g. VB6) and a thread switch occurs.
This is the behavior of Windows itself – so this also applies to managed applications. In 2.0 Microsoft decided to change this for managed apps to what you would actually expect – by default the impersonation token is now copied to new threads. This can be modified with the System.Thread.ExecutionContext class. Mike Woodring has an excellent sample which make it easy to examine this.
ASP.NET async modules and pages are also dependent on this behavior. For ASP.NET Microsoft decided to stick with the 1.1 way to not break existing async code that relies on running under the process identity. You can easily verify this by outputting a WindowsIdentity.GetCurrent().Name in an async module or page. This will always show the process identity name regardless of impersonation settings.
You can control how execution flow is handled with a file called aspnet.config which resides in the framework directory. Change it to the following settings:
<legacyUnhandledExceptionPolicy enabled=“false“ />
<SymbolReadingPolicy enabled=“1“ />
<legacyImpersonationPolicy enabled=“false“ />
<alwaysFlowImpersonationPolicy enabled=“true“ />
The important ones here are the two last settings. The first specifies if exceptions originating from background threads “bubble” up to the main thread. The 2nd settings is not documented at all.