简体   繁体   中英

Thread.CurrentPrincipal is authenticated but ClaimsPrincipal.Current is not

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM