Thread.CurrentPrincipal claims incorrectly to be anynomous Thread.CurrentPrincipal claims incorrectly to be anynomous asp.net asp.net

Thread.CurrentPrincipal claims incorrectly to be anynomous


This answer works, but is disappointing and alarming at the same time.

I spent 2 months working part time with MSDN technical support, and we finally found a work-around for this problem. I'm going to leave it to Microsoft to fix the problem, as it’s almost certainly an issue in the .net framework. But first, let me summarize the problem, give additional relevant background information and a few interesting things we found along the way.

The symptom was fleeting: Our website had a few reports of users who would authenticate with our website and see the correct state. But seemingly randomly, they’d be signed out of our website, or occasionally, experience the anonymous view. It was very frustrating, an nearly impossible to reproduce locally, in house.

Also on symptoms: through logging we saw mobile (iphone, ipad & android) browsers were disproportionately impacted, although all browsers and operating systems were impacted to some degree. And one last random symptom: It’d work for a user one day, not the next, and later in the afternoon, work again. Of course, switching browsers almost always fixed the problem.

We quickly assumed an auth issue, likely around the authentication cookie. The strange part was, I was able to prove (tracing) that the requests that were erroring included a proper cookie that I was able to decrypt, but that the .net framework was ignoring, in a non-deterministic way. I eventually began logging all requests that were in this state – auth cookie ignored by the .net framework, but seemingly valid to me, and found around 2% of my users were impacted.

I switched from using Thread.CurrentPrincipal.Identity to HttpContext.Current.User.Identity, to no avail, and tried a handful of other settings. Curiously, the only change I was able to make that made a dent was migrate to the .net 4 framework (from 3.5). The problem became an order of magnitude worst. Also tried various load balancer configurations, and was able to rule out multiple machine configurations – the same machine that issued the auth cookie would later reject it.

To re-iterate the symptoms: we had certain users (non-deterministic) who at times would not be able to user our website in an authenticated mode (also non-deterministic). Cute.

By now, the product team in Redmond was involved, and also stumped. But they did come up with a suggestion, which ultimately resolved the issue, here goes:Try forcing the Microsoft.net framework to use cookies as the authentication mode, as opposed to using a cookieless state:

<authentication mode="Forms">  <forms cookieless="UseCookies" /></authentication>

Flipped the switch and instantly the problematic requests ended (once I expired the session of those in an odd state).

While I’m glad that the problem was resolved – or rather worked around, it’s the non-deterministic handling of various browsers that worries me. Why would the .net framework see a browser one day, and treat it as supporting cookies, and later the same day say it should use a cookieless session?

My last concern is around how many other sites out there are losing 2% of their authenticated traffic without knowing? Considering the fix, it feels very much like a bug in the .net 4 framework.


Don't use this in ASP.NET authentication:

Thread.CurrentPrincipal = principal;

Instead stick to:

HttpContext.Current.User = principal;

For info see this article link text but more importantly the comments including the first and last ones - the article is old 2004 but the arguments are still valid today.

Therefore, instead of:

Thread.CurrentPrincipal.Identity.IsAuthenticated; // falseThread.CurrentPrincipal.Identity.Name; // null (or empty, unsure off hand)

You should use:

 HttpContext.Current.User.Identity...

In which case you can also use AuthenticateRequest instead of PostAuthenticateRequest because there is no Thread issue to workaround.


I would recommend that you begin by checking that the incoming web request actually has an authentication cookie and that it is valid. The forms authentication module takes the incoming web request and looks to see if it has a authentication cookie. If so then it attempts to decode it and then generate the principle using its contained value. As your principle is empty it means that either there was no authentication cookie provided in the request or there was an error decoding or it was decoded and found to be expired or it was decoded and oddly it has empty string as the username.

I recommend you create your own module that is called before the others and you check for yourself if the cookie is present and then if present decode it to see what it contains. That would give you more detail on what it happening. Your own module to reuse methods from the FormsAuthentication module to perform these actions. Such as....

ForsmAuthentication.Decrypt(...)