OpenId/AzureAd - .net core 6 中 HttpContext.User.Identity.Name 中的错误值

OpenId/AzureAd - wrong value in HttpContext.User.Identity.Name in .net core 6

我们的项目使用 Azure AD 对用户进行身份验证。

从 .net core 3 迁移到 .net core 6 后,我们开始两次获得类型为“http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name”的声明。您可以在下面的屏幕截图中看到。一个基本上是用户的全名 (John Doe),另一个是我们需要的电子邮件地址。

这破坏了我们的授权代码,因为我们使用 HttpContext.User.Identity.Name 在我们的数据库中查找用户。 属性 从上述类型的声明中获取 .Name 的价值。

在 .net core 3 下,我们得到了这两个声明,但全名有一个简单的类型“名称”,一个带有电子邮件地址 - “http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name ”。那效果很好。现在,由于我们两次收到相同的声明类型 - 第一个被填充为 .Name,这是全名而不是我们想要的电子邮件地址。

我已经有了一些解决方法。

有人正在更改 .Name 属性 的来源声明类型:

options.TokenValidationParameters.NameClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn";

另一个,有一个简单的 class 实现了 IClaimsTransformation 接口, 允许我 remove/fix 复制声明类型并使其像以前一样工作。

但这两种解决方案都不理想。 UPN 不保证它与 /name 声明相同(我们有很多用户使用 ../name 值注册),据我所知 - 它可能根本不可用。 第二种解决方案不可靠,因为很难区分全名和电子邮件地址(有人可能会将 @ 放在用户的全名中,或者带有地址的字段可能会向我们发送一些不是电子邮件地址形状的东西)。

所以,问题是 - 是什么导致了这个问题?什么可以控制这个?我认为这与 .net 中最近的更改有关,因为我们没有对 Azure AD 配置进行任何操作。旧代码仍然可以正常工作。

终于想通了。

我们安装了 Microsoft.AspNetCore.Authentication.OpenIdConnect Version="6.0.1"。这取决于 System.IdentityModel.Tokens.Jwt Version="6.10.0"

只需将 System.IdentityModel.Tokens.Jwt 更新到 6.10.2 或更高版本。这将解决问题。

This commit 添加新行到 ClaimTypeMapping.cs 那是映射“名称”(JwtRegisteredClaimNames.Name) 我能够在旧版本的 .net 核心中看到的声明类型。这会创建一个重复的“http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name”条目,因为 ClaimTypeMapping.cs 已经将“unique_name”(JwtRegisteredClaimNames.UniqueName) 映射到“http:/ /schemas.xmlsoap.org/ws/2005/05/identity/claims/name".

已通过 this 修复,它只是删除了该映射。

如果无法升级 - 可以这样做:

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove(JwtRegisteredClaimNames.Name);

应该在 app.UseAuthentication(); 行之前。

感谢您反馈您自己的问题。在更新了一些直接依赖项后,我们的一个产品间接依赖于 System.IdentityModel.Tokens.Jwt 的 6.10.0 版,我们遇到了同样的问题。

这一款产品怎么会突然出现登录问题,真是让我们百思不得其解。您的解决方案帮助我们朝着正确的方向前进! :)