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

Blazor Server(.NET Core3.1)获取当前用户AAD访问令牌失败求助

解决Blazor Server (.NET Core 3.1) 无法获取Azure AD访问令牌的问题

我帮你梳理下可能的问题点和对应的解决步骤,你可以一步步排查:

1. 确认Azure AD应用注册的API权限配置是否正确

要获取下游API的访问令牌,你的Blazor Server应用必须在Azure AD中注册并添加正确的委托权限(Delegated Permissions):

  • 登录Azure门户,找到你的Blazor Server应用注册
  • 进入「API权限」页面,点击「添加权限」,选择你的下游API
  • 添加对应的委托权限(比如access_as_user),然后点击「授予管理员同意」(这一步很关键,否则用户登录后无法获取令牌)

2. 完善Startup.cs中的认证配置

你已经设置了SaveTokens=true,但还需要确保OpenIdConnect的配置包含下游API的Scope,并且使用授权码流(ResponseType为code id_token):

using Microsoft.AspNetCore.Authentication.AzureAD.UI;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
        .AddAzureAD(options => Configuration.Bind("AzureAd", options));

    // 显式配置OpenIdConnect选项,确保获取access token
    services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
    {
        options.SaveTokens = true;
        // 添加下游API的Scope,格式为api://{下游API的ClientId}/{权限名称}
        options.Scope.Add("api://xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/access_as_user");
        // 指定授权码流,这是获取access token的必要条件
        options.ResponseType = "code id_token";

        // 可选:添加事件日志,调试时查看令牌获取情况
        options.Events = new OpenIdConnectEvents
        {
            OnTokenValidated = context =>
            {
                var accessToken = context.TokenEndpointResponse?.AccessToken;
                if (!string.IsNullOrEmpty(accessToken))
                {
                    System.Diagnostics.Debug.WriteLine("获取到Access Token: " + accessToken);
                }
                return Task.CompletedTask;
            }
        };
    });

    // 其他服务配置...
    services.AddHttpContextAccessor(); // 后续Blazor组件中需要用到
    services.AddRazorPages();
    services.AddServerSideBlazor();
}

3. 正确获取令牌的方式

在控制器中获取

不要从ClaimsPrincipal直接找令牌,access token存储在HttpContext的认证属性中,用GetTokenAsync方法获取:

[Authorize]
public class ApiCallController : Controller
{
    public async Task<IActionResult> CallDownstreamApi()
    {
        var accessToken = await HttpContext.GetTokenAsync("access_token");
        if (string.IsNullOrEmpty(accessToken))
        {
            // 令牌未获取到,跳转到重新认证
            return Challenge();
        }

        // 使用access token调用下游API
        var client = new HttpClient();
        client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);
        var response = await client.GetAsync("https://your-downstream-api-url");
        // 处理响应...
        return View();
    }
}

在Blazor组件中获取

Blazor组件无法直接访问HttpContext,需要注入IHttpContextAccessor:

@inject IHttpContextAccessor HttpContextAccessor
@if (HttpContextAccessor.HttpContext.User.Identity.IsAuthenticated)
{
    <p>已认证,正在获取令牌...</p>
}

@code {
    protected override async Task OnInitializedAsync()
    {
        if (HttpContextAccessor.HttpContext.User.Identity.IsAuthenticated)
        {
            var accessToken = await HttpContextAccessor.HttpContext.GetTokenAsync("access_token");
            if (!string.IsNullOrEmpty(accessToken))
            {
                // 使用令牌调用API
            }
            else
            {
                // 令牌为空,触发重新认证
                NavigationManager.NavigateTo("/MicrosoftIdentity/Account/SignIn", forceLoad: true);
            }
        }
    }
}

4. 验证回调地址和应用配置

  • 确保Azure AD应用注册中的「回复URL(Redirect URIs)」包含你的Blazor Server的回调地址,比如https://localhost:5001/signin-oidc(生产环境替换为实际域名)
  • 检查appsettings.json中的Azure AD配置是否正确:ClientId、TenantId、CallbackPath(默认是/signin-oidc)必须和Azure门户中的配置一致

5. 调试排查

如果还是拿不到令牌,可以通过以下方式排查:

  • 查看调试日志中的OnTokenValidated事件输出,确认是否从Azure AD获取到了access token
  • 使用浏览器的开发者工具,查看认证回调时的网络请求(/signin-oidc),检查返回的令牌数据中是否包含access_token

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:45:03