I'm using Claims based Authorization in my WebApi project and have a method where I check if the current Identity is authenticated. When I use ClaimsPrincipal.Current
the current Identity is not authenticated but when I use Thread.CurrentPrincipal
it is.
ClaimsPrincipal.Current.Identity.IsAuthenticated; //False
Thread.CurrentPrincipal.Identity.IsAuthenticated; //True
This seems strange especially since the MSDN says ClaimsPrincipal.Current just returns Thread.CurrentPrincipal:
Remarks
By default, Thread.CurrentPrincipal is returned. You can change this
behavior by setting the ClaimsPrincipalSelector property to specify a
delegate to be called to determine the current principal.
Can someone please explain me why ClaimsPrincipal
is not authenticated, while both, in theory, contain the same Identity?
In short, the documentation is incorrect to say that it returns Thread.CurrentPrincipal
by default.
What it actually returns is a ClaimsPrincipal
wrapping Thread.CurrentPrincipal
(if it's not, actually, already a ClaimsPrincipal
), using this constructor:
public ClaimsPrincipal(IPrincipal principal)
{
this.m_version = "1.0";
this.m_identities = new List<ClaimsIdentity>();
if (principal == null)
{
throw new ArgumentNullException("principal");
}
ClaimsPrincipal principal2 = principal as ClaimsPrincipal;
if (principal2 == null)
{
this.m_identities.Add(new ClaimsIdentity(principal.Identity));
}
else if (principal2.Identities != null)
{
this.m_identities.AddRange(principal2.Identities);
}
}
This, in turn, as you can hopefully see, is returning a ClaimsIdentity
that wraps the principal's identity (again, if it's not, actually, already a ClaimsIdentity
).
In constructing the ClaimsIdentity
, the only place I can see where it will end up not setting the authentication type (and thus creating an identity that's not authenticated) is here:
if(identity is WindowsIdentity)
{
try
{
this.m_authenticationType = identity.AuthenticationType;
}
catch(UnauthorizedAccessException)
{
this.m_authenticationType = null;
}
}
So, if the identity you access via Thread.CurrentPrincipal.Identity
is actually a WindowsIdentity
instance, and in the context in which you're running you've got restricted permissions, the constructed ClaimsIdentity
instance will have IsAuthenticated
as false.