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

使用Microsoft Identity Web时GetAccessTokenForUserAsync未返回自定义Claim

问题

使用Azure AD B2C登录流,在设置授权票据前调用Azure函数添加自定义Claim(userId)。Blazor应用内的Identity用户能正确看到该自定义Claim,但调用下游API时,通过ITokenAcquisition.GetAccessTokenForUserAsync获取的访问令牌不含userId Claim,传入ClaimsPrincipal对象后结果依旧:

var state = await _provider.GetAuthenticationStateAsync();
var principal = state.User;
var accessToken = await tokenAcquisition.GetAccessTokenForUserAsync(
    [$"{configuration["DownstreamApis:MyAPI-API:AppIdUri"]}/{configuration["DownstreamApis:MyAPI:Scope"]}"], 
    user: principal);

同时发现角色也未映射,HttpContext.User中存在这些Claim,但调用GetAccessTokenForUserAsync时未被带入访问令牌。

Blazor中间件配置

builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
    .EnableTokenAcquisitionToCallDownstreamApi()
    .AddInMemoryTokenCaches();

builder.Services.AddOptions<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme).Configure(oidcOptions =>
{
    oidcOptions.Scope.Add(OpenIdConnectScope.OfflineAccess);
});

API中间件配置

builder.Services
    .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApi(o =>
    {
        var b2cConfig = builder.Configuration.GetSection("AzureAdB2C");
        var tenantId = b2cConfig.GetValue<string>("TenantId");
        var domains = b2cConfig.GetSection("ValidIssuerDomains").Get<List<string>>();
        var validIssuers = domains?.Select(domain => $"https://{domain}/{tenantId}/v2.0/");
        o.TokenValidationParameters.ValidIssuers = validIssuers;
        o.TokenValidationParameters.RoleClaimType = "role";
        o.TokenValidationParameters.NameClaimType = "sub";
        o.IncludeErrorDetails = true;        
        
    }, options => builder.Configuration.Bind("AzureAdB2C", options));

解决方案

1. 让Azure AD B2C策略将自定义Claim输出到访问令牌

登录Azure门户,进入目标B2C租户,打开对应的用户流或自定义策略:

  • 在应用程序声明设置中,将userId及角色Claim添加到访问令牌的输出声明列表,不要仅添加到ID令牌。
  • 保存并发布策略变更。

2. 确认API权限与请求范围正确

  • 在Azure AD B2C中,确保Blazor应用已被授予下游API的Delegated类型权限。
  • 调用GetAccessTokenForUserAsync时,验证传入的范围格式为{AppIdUri}/{ScopeName},例如https://yourtenant.onmicrosoft.com/api/access_as_user。

3. 配置TokenAcquisition的Claim映射规则

在Blazor的服务配置中,添加Claim映射,确保用户端的Claim被带入下游API的请求令牌:

builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
    .EnableTokenAcquisitionToCallDownstreamApi(options =>
    {
        // 映射自定义userId Claim
        options.ClaimMapping.Add("userId", "userId");
        // 映射角色Claim
        options.ClaimMapping.Add("role", "role");
    })
    .AddInMemoryTokenCaches();

4. 检查API端的令牌验证配置

确认API的TokenValidationParameters配置正确,确保令牌的Issuer、SigningKey等参数无误,保证自定义Claim能被正常解析。

5. 清理令牌缓存重试

若存在旧令牌缓存,先清除用户的缓存令牌再重新获取:

await tokenAcquisition.RemoveAccountAsync(principal);
// 重新调用GetAccessTokenForUserAsync获取新令牌

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 03:23:17