Azure AD B2C:User.Identity.Name为空但私有声明含名称的解决咨询
问题原因与解决方案
为什么User.Identity.Name为空?
User.Identity.Name属性默认是从**http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name**这个标准声明类型中取值的。而Azure AD B2C返回的用户名称信息,往往存储在其他声明字段里(比如常见的name、email,或者你自定义的声明类型),所以默认情况下Name属性找不到对应的值,就会显示为空。你看到的私有变量m_instance_claims[9]里的内容,其实是Azure AD B2C返回的所有原始声明集合,只是这个声明的类型没有和User.Identity.Name做映射。
如何让User.Identity.Name获取到目标声明的值?
根据你使用的认证方式(通常是OWIN OpenID Connect),可以通过以下几种方式解决:
1. 在OIDC配置中指定NameClaimType
如果你是用OWIN中间件配置Azure AD B2C认证,可以直接在TokenValidationParameters里指定NameClaimType为目标声明的类型:
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions { ClientId = "你的客户端ID", Authority = "你的B2C授权端点", // 其他必要配置... TokenValidationParameters = new TokenValidationParameters { // 替换成你在m_instance_claims[9]里看到的声明Type(比如"name") NameClaimType = "name" } });
2. 使用ClaimActions映射声明
同样在OIDC配置中,你可以用ClaimActions把JSON令牌里的字段映射到标准ClaimTypes.Name:
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions { // 其他配置... ClaimActions.MapJsonKey(ClaimTypes.Name, "name"); // 第一个参数是标准声明类型,第二个是B2C返回的字段名 });
3. 在Web.config中配置声明映射
如果你已经在Web.config里添加了相关配置,可以补充完整声明类型的映射规则:
<system.identityModel> <identityConfiguration> <securityTokenHandlers> <securityTokenHandlerConfiguration> <!-- 设置Name属性对应的声明类型 --> <nameClaimType value="name" /> </securityTokenHandlerConfiguration> </securityTokenHandlers> </identityConfiguration> </system.identityModel>
4. 认证成功后手动添加声明
如果上述方式都不生效,还可以在认证成功的事件中手动处理:
Notifications = new OpenIdConnectAuthenticationNotifications { SecurityTokenValidated = context => { // 找到你需要的声明(替换成实际的声明Type) var targetClaim = context.AuthenticationTicket.Identity.FindFirst("name"); if (targetClaim != null) { // 添加标准Name声明,这样User.Identity.Name就能取到值了 context.AuthenticationTicket.Identity.AddClaim(new Claim(ClaimTypes.Name, targetClaim.Value)); } return Task.CompletedTask; } }
注意事项
先确认m_instance_claims[9]里那个声明的Type属性到底是什么(比如是name、email还是自定义的URI),然后把上面代码里的对应值替换成这个Type,这样映射才会准确。
内容的提问来源于stack exchange,提问作者aBlaze
相关产品推荐
相关产品推荐

