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

Blazor客户端.NET Core:如何从OIDC令牌在Server API中获取用户名

Blazor项目API端获取用户名问题

环境配置

客户端(Blazor)配置

builder.Services.AddOidcAuthentication(opt =>
{
    opt.ProviderOptions.Authority = "https://x.y.z/oidc";
    opt.ProviderOptions.ClientId = "client";
    opt.ProviderOptions.DefaultScopes.Add("email");
    opt.ProviderOptions.DefaultScopes.Remove("profile"); 
    opt.ProviderOptions.ResponseType = "code";   
});

var IHttpServiceClient = builder.Services.AddHttpClient<IBaseHttpService,BaseHttpService>();

builder.Services.AddScoped<CustomAuthorizationMessageHandler>();

IHttpServiceClient.AddHttpMessageHandler<CustomAuthorizationMessageHandler>();

CustomAuthorizationMessageHandler实现:

public class CustomAuthorizationMessageHandler:AuthorizationMessageHandler
{
    public CustomAuthorizationMessageHandler(IAccessTokenProvider provider , NavigationManager nav) :base(provider, nav)
    {
        ConfigureHandler(authorizedUrls: new[] { nav.BaseUri });
    }
}

客户端可正常获取用户名:

username = (await _authenticationStateProvider.GetAuthenticationStateAsync()).User.Identity!.Name!;

服务端API配置

builder.Services
.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{      
    options.Authority = "https://x.y.z/oidc";
    options.TokenValidationParameters.ValidateAudience = false;
    options.TokenValidationParameters.ValidateIssuer = true;
});

问题

在API端点中尝试获取用户名时:

string username = User.Identity.Name;  // 为空
string username = User.Claims.Where(p => p.Type == ClaimTypes.NameIdentifier).First().Value; // 包含GUID前缀

前端<AuthorizeView>显示的Claim中存在name字段(值为emi),但该Claim未传递到API端,需要找到正确获取用户名的方法,避免截取GUID前缀的方式。

解决方案

1. 确保Access Token包含name声明

前端<AuthorizeView>展示的是ID Token中的声明,而API接收的是Access Token,两者的声明内容可能不同。需要检查OIDC提供商的配置:

  • 确认客户端请求的Scope包含profile(即使前端移除了profile Scope,若API需要该声明,需将其添加回客户端的DefaultScopes,因为Access Token的内容由请求的Scope决定);
  • 在OIDC提供商后台配置,确保Access Token中包含name声明(比如IdentityServer中,需确保客户端的AllowedScopes包含profile,且用户的name字段已正确赋值)。

2. 配置JWT Bearer的声明映射

默认ASP.NET Core会将JWT中的name声明映射到ClaimTypes.Name,但如果映射异常,可手动指定:

builder.Services.AddAuthentication("Bearer")
    .AddJwtBearer("Bearer", options =>
    {
        options.Authority = "https://x.y.z/oidc";
        options.TokenValidationParameters.ValidateAudience = false;
        options.TokenValidationParameters.ValidateIssuer = true;
        // 指定Name声明的映射关系
        options.TokenValidationParameters.NameClaimType = "name";
        // 若需要角色声明,可同时指定
        // options.TokenValidationParameters.RoleClaimType = "role";
    });

配置后,User.Identity.Name即可直接获取到name声明的值。

3. 验证传递的Token类型

确认CustomAuthorizationMessageHandler传递给API的是Access Token而非ID Token。可在API端点中打印所有Claim,检查是否存在name:

var allClaims = User.Claims.Select(c => $"{c.Type}: {c.Value}").ToList();
// 输出allClaims查看内容

若没有name声明,说明Access Token本身不包含该字段,需回到OIDC提供商调整配置。

4. 调整OIDC提供商的SubjectId配置(可选)

如果希望ClaimTypes.NameIdentifier直接返回用户名而非GUID,可在OIDC提供商(如IdentityServer)中,将用户的SubjectId设置为用户名。但此操作可能影响依赖SubjectId的其他功能,需谨慎评估。


内容的提问来源于stack exchange,提问作者Dorian

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 13:07:40