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

使用OpenID Connect在Blazor Server中获取Azure B2C签发的JWT令牌

可以获取到Azure B2C签发的原始JWT令牌,不需要自行生成,具体实现流程如下:

前置配置

首先确保你的项目已经完成以下基础配置:

  • 在Program.cs中注册Microsoft Identity服务时开启令牌保存,同时启用令牌获取能力和令牌缓存:
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAdB2C"), options =>
    {
        // 必须开启,才会把Azure返回的令牌存到认证票据中
        options.SaveTokens = true;
    })
    // 启用令牌获取服务,对应你用MSAL.js的acquireTokenSilent能力
    .EnableTokenAcquisitionToCallDownstreamApi()
    // 配置内存令牌缓存,生产环境可替换为分布式缓存
    .AddInMemoryTokenCaches();

// 注册HttpContext访问服务(如果你用方式1获取令牌需要加)
builder.Services.AddHttpContextAccessor();
组件内获取令牌的两种实现方式

方式1:通过HttpContext获取(仅适用页面首次预渲染阶段)

直接在LoginDisplay.razor组件中注入IHttpContextAccessor,然后调用GetTokenAsync方法获取:

@inject IHttpContextAccessor HttpContextAccessor
@code
{
    [CascadingParameter] private Task<AuthenticationState> authenticationStateTask { get; set; }

    protected override async Task OnInitializedAsync()
    {
        var authState = await authenticationStateTask;
        var user = authState.User;
        var identity = user.Identity as ClaimsIdentity;
        if (identity != null && identity.IsAuthenticated)
        {
            IEnumerable<Claim> claims = identity.Claims;
            
            // 在此处获取JWT令牌
            if (HttpContextAccessor.HttpContext != null)
            {
                // 身份令牌id_token
                var idToken = await HttpContextAccessor.HttpContext.GetTokenAsync("id_token");
                // 访问令牌access_token
                var accessToken = await HttpContextAccessor.HttpContext.GetTokenAsync("access_token");
            }
        }
    }
}

注意:该方式仅在页面首次加载的预渲染阶段可用,Blazor Server建立SignalR长连接之后,HttpContext会被释放,此时调用会返回null。

方式2:通过ITokenAcquisition服务获取(推荐全场景使用)

这是微软官方提供的令牌获取服务,能力和你之前在SPA中使用的MSAL.acquireTokenSilent完全一致,会自动处理令牌缓存、刷新逻辑,不需要自行处理HttpContext:
首先在组件中注入ITokenAcquisition服务:

@inject ITokenAcquisition TokenAcquisition
@code
{
    [CascadingParameter] private Task<AuthenticationState> authenticationStateTask { get; set; }

    protected override async Task OnInitializedAsync()
    {
        var authState = await authenticationStateTask;
        var user = authState.User;
        var identity = user.Identity as ClaimsIdentity;
        if (identity != null && identity.IsAuthenticated)
        {
            IEnumerable<Claim> claims = identity.Claims;
            
            // 在此处获取JWT令牌
            // 替换为你在Azure B2C中注册的下游API作用域
            var scopes = new[] { "你的API作用域,例如https://xxx.onmicrosoft.com/xxx/access_as_user" };
            try
            {
                var accessToken = await TokenAcquisition.GetAccessTokenForUserAsync(scopes);
                // 此处拿到的就是Azure B2C签名的原始JWT令牌
            }
            catch (MicrosoftIdentityWebChallengeUserException)
            {
                // 处理需要用户重新交互的场景,例如令牌过期无法刷新、权限变更
            }
        }
    }
}
GetTokenAsync返回null的排查方案

如果调用HttpContext.GetTokenAsync返回null,可按以下步骤排查:

  1. 确认OpenIdConnect配置中SaveTokens = true已正确设置
  2. 确认调用时机在HttpContext有效阶段,若为长连接建立后的交互场景,直接改用ITokenAcquisition服务即可
  3. 确认用户已完成完整的Azure B2C登录流程,身份认证已成功

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 08:24:10