IdentityServer4无法显示全部用户Claims的问题求助
嘿,我之前也踩过这个坑!IdentityServer4不会默认把所有自定义Claims都自动返回,得做些配置调整才行,咱们一步步来搞定:
1. 先检查Claim的类型命名
你代码里写的new Claim("e-mail", "bobasterman@gmail.com")用了自定义的键名,但IdentityServer对标准Claim类型有默认识别逻辑,比如邮箱对应的标准类型是ClaimTypes.Email(底层字符串是http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress)。虽然自定义键也能用,但先统一用标准类型能避免很多识别问题:
new Claim(ClaimTypes.Name, "Bob Asterman"), new Claim(ClaimTypes.Email, "bobasterman@gmail.com"), new Claim("website", "https://bob.example.com"), new Claim("age", "28"), new Claim("game-favorite", "The Legend of Zelda")
2. 配置IdentityResources,告诉IdentityServer要返回这些Claims
IdentityServer需要明确知道哪些Claims属于可对外暴露的身份资源。你需要在IdentityServer的配置类(比如Config.cs)里,添加或扩展对应的IdentityResource,把需要的Claims包含进去:
方式一:扩展默认的Profile资源
默认的profile资源包含部分基础Claims,但不包括自定义的age、game-favorite,所以可以扩展它:
public static IEnumerable<IdentityResource> GetIdentityResources() { var profileResource = new IdentityResources.Profile(); // 把自定义Claims添加到profile资源中 profileResource.UserClaims.Add("age"); profileResource.UserClaims.Add("game-favorite"); return new List<IdentityResource> { new IdentityResources.OpenId(), // 必须的openid scope profileResource, new IdentityResources.Email() // 如果用标准邮箱Claim,需要添加这个资源 }; }
方式二:创建自定义身份资源
如果你的Claims比较特殊,也可以单独创建一个自定义资源:
public static IEnumerable<IdentityResource> GetIdentityResources() { var customUserProfile = new IdentityResource( name: "custom-profile", displayName: "Custom User Profile", userClaims: new List<string> { "age", "game-favorite" }); return new List<IdentityResource> { new IdentityResources.OpenId(), new IdentityResources.Profile(), new IdentityResources.Email(), customUserProfile }; }
3. 确保客户端配置包含对应的Scopes
接下来要保证你的客户端(Client)配置里,AllowedScopes包含了上面定义的所有资源。比如用了扩展的profile、email,或者自定义的custom-profile,都要加进去:
public static IEnumerable<Client> GetClients() { return new List<Client> { new Client { ClientId = "your-client-id", ClientSecrets = { new Secret("your-client-secret".Sha256()) }, AllowedGrantTypes = GrantTypes.ResourceOwnerPassword, // 关键:添加需要的scopes AllowedScopes = new List<string> { IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, IdentityServerConstants.StandardScopes.Email, "custom-profile" // 如果用了自定义资源,记得加这个 }, AllowOfflineAccess = true } }; }
4. 验证Token内容
最后可以用JWT解析工具(比如本地的调试工具或者在线解析器)查看生成的ID Token,确认所有Claims是否已经包含进去。如果还是没显示,再检查两个点:
- 请求Token时,Scope参数是否包含了对应的资源(比如
profile、email、custom-profile) - TestUser里的Claims有没有拼写错误(比如你代码里的"e-mail"是不是应该统一为"email"?)
这样调整之后,你的TestUser的所有Claims应该就能正常显示啦!
内容的提问来源于stack exchange,提问作者Leonardo Oliveira

