You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 15:47:34