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

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

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

这看起来很奇怪,特别是因为MSDN说 ClaimsPrincipal.Current只返回Thread.CurrentPrincipal:

备注

默认情况下,返回Thread.CurrentPrincipal。 您可以通过设置ClaimsPrincipalSelector属性来指定要调用的委托来确定当前主体,从而更改此行为。

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

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

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

 public ClaimsPrincipal(IPrincipal principal) { this.m_version = "1.0"; this.m_identities = new List(); 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 ,我唯一可以看到它最终没有设置身份validation类型(从而创建未经过身份validation的身份)的地方在这里:

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

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