为什么ClaimTypes.NameIdentifier没有映射到“sub”?

问题描述 投票:0回答:4

使用 ASP.NET Core 2.2 和 Identity Server 4 我有以下控制器:

[HttpGet("posts"), Authorize]
public async Task<IActionResult> GetPosts() {

  var authenticated = this.User.Identity.IsAuthenticated;

  var claims = this.User.Identities.FirstOrDefault().Claims;

  var id = this.User.FindFirstValue(ClaimTypes.NameIdentifier);

}

我得到了所有

claims
id
为空...

我检查了

claims
中的所有值,并且我有一个值为 1 的“子”声明。

为什么 ClaimTypes.NameIdentifier 没有映射到“sub”?

c# asp.net-core identityserver4 asp.net-core-2.2
4个回答
34
投票
  1. 为了不让 Microsoft Identity 覆盖声明名称,您必须在 API 启动中的

    JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
    之前使用
    app.UseAuthentication()

  2. 使用直接“sub”声明而不是 ClaimThypes.NameIdentifier,例如

    var id = this.User.FindFirstValue("sub");

如需进一步参考,请参阅详细讨论: https://github.com/IdentityServer/IdentityServer4/issues/2968#issuecomment-510996164


11
投票

我假设在 OIDC 配置中,您已使用以下命令清除了 Microsoft JWT 令牌处理程序上的入站声明类型映射:

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

然后您可以手动设置声明的声明类型映射

sub
:

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Add("sub", ClaimTypes.NameIdentifier);

7
投票

静态字符串

ClaimTypes.NameIdentifier
具有以下值:
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier

所以难怪它不能用来查找

sub
索赔的价值。

如果您知道

sub
声明包含用户 ID,则只需使用
sub
字符串即可进行查找。

ClaimTypes.NameIdentifier
仅在使用默认入站声明类型映射创建
ClaimsPrincipal
时才用于查找用户 ID,该映射将
sub
声明映射到
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier

但即使在这种情况下,使用

userManager.Options.ClaimsIdentity.UserIdClaimType
也更合适,因为这是原始映射中使用的实际值(默认为
ClaimTypes.NameIdentifier
,但可以自定义)。

(但是,是的,这整个映射非常混乱,并且存在许多 Github 问题,甚至 MS 开发人员也感叹这是仅仅由于遗留原因而存在的邪恶。)


0
投票
从 .NET 8 Preview 7 开始,

Nan Yu 的答案不再有效,可能是由于此重大更改的结果。我认为从那时起,惯用的方法就是在调用

JwtBearerOptions.MapInboundClaims
时将
false
设置为
AuthenticationBuilder.AddJwtBearer


            services
                .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(jwtBearerOptions =>
                {
                    jwtBearerOptions.MapInboundClaims = false;
                });
© www.soinside.com 2019 - 2024. All rights reserved.