.NET 8 MAUI Blazor客户端读取新Identity Bearer Token遇问题求助
解决.NET 8内置Identity非JWT Token的声明读取问题
问题根源
.NET 8内置Identity默认可能返回参考令牌(Reference Token)而非JWT自包含令牌。参考令牌只是一串不携带用户信息的标识字符串,无法直接用JwtSecurityTokenHandler.ReadToken解析,必须向Identity服务的内省端点请求获取令牌的声明数据。
解决方案一:通过内省端点获取声明
1. 服务端配置内省权限
确保Identity服务端的客户端配置允许内省请求,示例如下:
builder.Services.AddIdentityServer() .AddInMemoryClients(new List<Client> { new Client { ClientId = "your-client-id", ClientSecrets = { new Secret("your-client-secret".Sha256()) }, AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials, // 匹配你的授权类型 AllowedScopes = { "openid", "profile", "roles", "your-api-scope" }, AccessTokenType = AccessTokenType.Reference, // 默认是参考令牌,可省略 Enabled = true } }) .AddInMemoryApiScopes(new List<ApiScope> { new ApiScope("your-api-scope", "Your API") }) .AddAspNetIdentity<IdentityUser>();
2. 客户端发送内省请求解析令牌
在需要读取令牌的客户端代码中,向Identity的内省端点发送POST请求,获取声明信息:
using System.Net.Http.Headers; using System.Text; using System.Text.Json; // 替换为你的Identity服务地址 var introspectEndpoint = "https://your-identity-server/connect/introspect"; var clientId = "your-client-id"; var clientSecret = "your-client-secret"; var accessToken = tokenResponse.AccessToken; using var httpClient = new HttpClient(); // 客户端凭证Basic认证 var authBase64 = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{clientId}:{clientSecret}")); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authBase64); var formData = new Dictionary<string, string> { { "token", accessToken }, { "token_type_hint", "access_token" } }; var response = await httpClient.PostAsync(introspectEndpoint, new FormUrlEncodedContent(formData)); response.EnsureSuccessStatusCode(); var introspectJson = await response.Content.ReadAsStringAsync(); var introspectData = JsonSerializer.Deserialize<JsonElement>(introspectJson); if (introspectData.GetProperty("active").GetBoolean()) { // 读取声明,注意Claim名称对应内省返回的字段 string userId = introspectData.GetProperty("sub").GetString(); // 对应JwtRegisteredClaimNames.NameId string name = introspectData.GetProperty("name").GetString(); // 对应JwtRegisteredClaimNames.UniqueName string role = introspectData.GetProperty("role").GetString(); // 若内省返回email,可直接读取:introspectData.GetProperty("email").GetString() string email = loginModel.Email; } else { // 处理令牌无效的情况 }
解决方案二:配置返回JWT自包含令牌
如果希望继续使用原有JWT解析代码,可以修改客户端配置,让Identity返回JWT:
new Client { // 其他配置... AccessTokenType = AccessTokenType.Jwt // 强制返回JWT令牌 }
配置完成后,原有的JwtSecurityTokenHandler解析代码即可正常工作。
内容的提问来源于stack exchange,提问作者Dani
相关产品推荐
相关产品推荐

