Thread.CurrentPrincipal已经过身份验证,但ClaimsPrincipal.Current不是

时间:2013-03-11 15:06:55

标签: c# asp.net-web-api .net-4.5 identity claims-based-identity

我在WebApi项目中使用基于声明的授权,并且有一种方法可以检查当前身份是否经过身份验证。当我使用ClaimsPrincipal.Current时,当前身份未经过身份验证,但是当我使用Thread.CurrentPrincipal时,它就是。

ClaimsPrincipal.Current.Identity.IsAuthenticated; //False
Thread.CurrentPrincipal.Identity.IsAuthenticated; //True

这似乎很奇怪,因为MSDN says ClaimsPrincipal.Current只返回Thread.CurrentPrincipal:

  

说明

     

默认情况下,返回Thread.CurrentPrincipal。你可以改变这个   通过设置ClaimsPrincipalSelector属性来指定一个行为   代表被要求确定当前的委托人。

有人可以解释一下为什么ClaimsPrincipal未经过身份验证,而理论上两者都包含相同的身份吗?

1 个答案:

答案 0 :(得分:10)

简而言之,说明文档默认返回Thread.CurrentPrincipal是不正确的。

实际返回的是ClaimsPrincipal 包装 Thread.CurrentPrincipal(如果不是,实际上已经是ClaimsPrincipal),使用此构造函数:

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);
    }
}

反过来,正如您可能希望看到的那样,返回ClaimsIdentity 包裹校长的身份(再次,如果不是,实际上,已经是ClaimsIdentity )。

在构建ClaimsIdentity时,我唯一能看到它最终没有设置身份验证类型的位置(从而创建一个未经过身份验证的身份)就在这里:

if(identity is WindowsIdentity)
{
   try
   {
      this.m_authenticationType = identity.AuthenticationType;
   }
   catch(UnauthorizedAccessException)
   {
      this.m_authenticationType = null;
   }
}

因此,如果您通过Thread.CurrentPrincipal.Identity访问的身份实际上是WindowsIdentity实例,并且在您运行的上下文中,您拥有受限制的权限,构造的ClaimsIdentity实例将IsAuthenticated设为false。