Thread.CurrentPrincipal 已通过身份验证,但 ClaimsPrincipal.Current 未通过身份验证 [英] Thread.CurrentPrincipal is authenticated but ClaimsPrincipal.Current is not

查看:35
本文介绍了Thread.CurrentPrincipal 已通过身份验证,但 ClaimsPrincipal.Current 未通过身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

This seems strange especially since the MSDN says ClaimsPrincipal.Current just returns Thread.CurrentPrincipal:

备注

默认情况下,返回 Thread.CurrentPrincipal.你可以改变这个通过设置 ClaimsPrincipalSelector 属性来指定一个行为委托被调用以确定当前主体.

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.

谁能解释一下为什么 ClaimsPrincipal 没有经过身份验证,而理论上两者都包含相同的身份?

Can someone please explain me why ClaimsPrincipal is not authenticated, while both, in theory, contain the same Identity?

推荐答案

简而言之,文档中说它默认返回 Thread.CurrentPrincipal 是错误的.

In short, the documentation is incorrect to say that it returns Thread.CurrentPrincipal by default.

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

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

反过来,正如您所看到的,这将返回一个 ClaimsIdentity,它包装主体的身份(同样,如果不是,实际上,已经是 ClaimsIdentity).

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).

在构建 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;
   }
}

因此,if您通过 Thread.CurrentPrincipal.Identity 访问的身份实际上是一个 WindowsIdentity 实例,并且在您所在的上下文中'正在运行您的权限受限,构建的 ClaimsIdentity 实例会将 IsAuthenticated 设为 false.

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.

这篇关于Thread.CurrentPrincipal 已通过身份验证,但 ClaimsPrincipal.Current 未通过身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆