Azure AD OWIN认证MVC应用中:User.Identity.Name为null时如何获取Claims中的name及preferred_username
解决Azure AD OWIN中Identity.Name为空,从Claims提取name/preferred_username的问题
我之前也碰到过完全一样的情况——用Azure AD OWIN做身份认证时,HttpContext.User.Identity.Name和User.Identity.Name都是null,但Identity的Claims属性里明明躺着name和preferred_username这些我们需要的值。这本质是因为OWIN默认的NameClaimType和Azure AD返回的声明类型不匹配,导致Identity没有自动填充Name属性。下面给你几个实用的解决办法:
方法1:直接从Claims集合提取(快速临时方案)
最直接的方式就是从Claims集合里根据声明类型精准取值:
// 获取name属性值 var displayName = User.Identity.Claims .FirstOrDefault(claim => claim.Type == "name") ?.Value; // 获取preferred_username属性值 var preferredUsername = User.Identity.Claims .FirstOrDefault(claim => claim.Type == "preferred_username") ?.Value;
小提醒:调试时可以先确认Claims里的Type是否完全匹配,虽然Azure AD的
name和preferred_username通常是不带命名空间前缀的纯字符串,但个别场景下可能会有差异,先核实准没错。
方法2:封装扩展方法(复用性拉满)
如果项目里多处需要提取这些声明,建议封装成扩展方法,让代码更整洁:
public static class IdentityClaimExtensions { public static string GetDisplayName(this IIdentity identity) { var claimsIdentity = identity as ClaimsIdentity; return claimsIdentity?.Claims .FirstOrDefault(c => c.Type == "name")?.Value; } public static string GetPreferredUsername(this IIdentity identity) { var claimsIdentity = identity as ClaimsIdentity; return claimsIdentity?.Claims .FirstOrDefault(c => c.Type == "preferred_username")?.Value; } }
用的时候就非常简洁:
var userName = User.Identity.GetDisplayName(); var userEmail = User.Identity.GetPreferredUsername();
方法3:配置OWIN映射NameClaimType(一劳永逸)
要是你希望User.Identity.Name直接返回name或preferred_username的值,可以在Startup.cs的认证配置里指定NameClaimType:
public void ConfigureAuth(IAppBuilder app) { app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions { ClientId = "你的ClientId", Authority = "你的Authority地址", RedirectUri = "你的RedirectUri", // 其他必要配置... TokenValidationParameters = new TokenValidationParameters { // 将NameClaimType映射到你需要的声明类型 NameClaimType = "name", // 也可以换成"preferred_username" RoleClaimType = "roles" } }); }
配置完之后,User.Identity.Name就会自动填充为你指定的声明值,不用再手动提取啦。
内容的提问来源于stack exchange,提问作者Jerry
相关产品推荐
相关产品推荐

