ASP.NET 核心 JWT 身份验证更改声明(子)

ASP.NET Core JWT authentication changes Claims (sub)

我有一个使用 JWT 身份验证的 ASP.NET 核心 API。简单设置:

....
string authority = $"https://{configuration["Auth:Authority"]}";
string audience = configuration["Auth:Audience"];

return builder.AddJwtBearer(options =>
{
    options.Authority = authority;
    options.Audience = audience;

    options.TokenValidationParameters = new TokenValidationParameters
    {
        // NameClaimType = "http://schemas.org/email"
        // NameClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/email"
        // NameClaimType = "sub"
    };
});

(如您所见,注释代码,我一直在尝试多种设置)

当我解码 JWT(使用 jwt.io)时,我看到 JWT 中有声明 "sub" 并且具有字符串值(dbo 中用户的内部 ID)

{
  "nbf": 1592585433,
  "exp": 1592585763,
  "iss": "https://*************",
  "aud": "api_10",
  "sub": "142",
  "scope": [
    "openid",
    "api_10"
  ]
}

问题是 dotnet switch sub to name claim。这个returns没有(0)个结果:

principal.Claims.Where(w => w.Type == "sub")

这个returns userId我需要"142":

principal.Claims.Where(w => w.Type == ClaimTypes.Name || ClaimTypes.NameIdentifier)

这是怎么回事?!我的子索赔去哪儿了?

只需在 API 的 ConfigureServices 方法上添加 JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();。它也在其他评论中提出了建议。我在 sample repo.

上验证了它

此问题是因为 OIDC StandardClaims 在 JWT 令牌处理程序上重命名。通过添加 JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();,您将清除 JWT 令牌处理程序上的入站声明类型映射。

阅读更多here