为何Asp.Net Core 2.0项目中IdentityServer4的Token不含用户声明?
看起来你已经完成了基础配置,但Token里没出现角色声明,大概率是几个关键环节没衔接到位,我来帮你一步步排查解决:
1. 先给"role" Scope在IdentityServer里做注册
你在Client的AllowedScopes里加了"role",但IdentityServer需要先明确这个Scope的定义。建议把角色作为身份资源注册,在Config.cs的GetIdentityResources方法里添加:
public static IEnumerable<IdentityResource> GetIdentityResources() { return new List<IdentityResource> { new IdentityResources.OpenId(), new IdentityResources.Profile(), new IdentityResources.Email(), // 新增角色身份资源,指定返回的Claim类型 new IdentityResource("role", "用户角色信息", new[] { JwtClaimTypes.Role }) }; }
只有注册后,IdentityServer才会把角色声明纳入Token的返回范围。
2. 确认WPF客户端请求Token时包含"role" Scope
客户端在发起Token请求时,必须明确指定要获取"role"这个Scope,比如请求代码里的Scope列表要加上它:
var requestedScopes = new[] { "openid", "profile", "email", "offline_access", "fiver_auth_api", "role" }; // 用这个列表去请求Token
哪怕Client配置里允许了该Scope,客户端不主动请求的话,IdentityServer也不会返回对应的声明。
3. 给API端配置Claim映射
Asp.Net Core默认的角色Claim类型和JWT里的role声明不匹配,需要在API的Startup.cs里做映射配置,让API能正确识别Token里的角色:
public void ConfigureServices(IServiceCollection services) { // ...其他服务配置 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.Authority = "你的IdentityServer地址"; options.Audience = "fiver_auth_api"; // 指定JWT中的角色Claim类型 options.TokenValidationParameters = new TokenValidationParameters { RoleClaimType = JwtClaimTypes.Role }; }); }
这一步是让[Authorize(Roles = "Admin")]特性能正确识别Token里的角色声明。
4. 检查Access Token的内容(别只看Id Token)
你设置了AlwaysIncludeUserClaimsInIdToken=true,但WPF访问API用的应该是Access Token,要确认Access Token里包含角色声明。可以用jwt.io解析Token查看内容,如果Access Token里没有,可在Client配置里补充:
new Client { // ...其他配置 AlwaysSendClientClaims = true, AlwaysIncludeUserClaimsInIdToken = true }
5. 补全TestUser的必要配置
你的TestUser里SubjectId别留空,要填一个唯一标识值,同时Scope Claim里也加上"role":
return new List<TestUser> { new TestUser { SubjectId = "1", // 填唯一ID Username = "Alice", Password = "yourpassword", Claims = new List<Claim> { new Claim(JwtClaimTypes.Email, "AliceSmith@email.com"), new Claim(JwtClaimTypes.EmailVerified, "true", ClaimValueTypes.Boolean), new Claim(JwtClaimTypes.Role, "Admin"), new Claim(JwtClaimTypes.Scope, "openid offline_access fiver_auth_api role") } } };
做完这些配置后,重新生成Token并解析检查,确认role声明存在后,API的角色授权特性就能正常生效了。
内容的提问来源于stack exchange,提问作者Alexandra Damaschin

