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

从Blazor WebAssembly调用Azure Functions受保护API遇401问题求助

解决方案:Blazor WASM 调用 AAD B2B 保护的 Azure Functions 401 问题

核心配置排查(最可能的遗漏点)

1. 令牌受众精确匹配

  • 确认Azure Functions的应用服务认证设置中,Allowed Token Audiences严格匹配自定义应用ID URI(api://NAME),注意大小写、是否带末尾斜杠——AAD受众校验为精确匹配,任何差异都会导致401。
  • 用本地JWT解析工具检查Blazor获取的accessToken:查看aud声明是否等于api://NAME,若为应用注册的clientId,说明Scope配置错误。

2. Scope配置必须完整

Blazor请求令牌时,Scope必须是完整权限路径(api://NAME/user_impersonation),而非仅user_impersonation。AAD要求自定义API的Scope必须包含应用ID URI前缀。
修正后的代码示例:

builder.Services.AddMsalAuthentication(options => {
    builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
    // 明确指定完整Scope路径
    options.ProviderOptions.DefaultAccessTokenScopes.Add("api://NAME/user_impersonation");
})

同步确认appsettings.json中AzureAd:Scopes值为完整路径。

3. CORS配置必须允许凭据

  • Azure静态网站CORS设置:允许来源为Blazor域名(如https://your-static-site.azurestaticapps.net),并勾选允许凭据(AAD认证令牌需携带凭据头)。
  • Azure Functions的CORS设置需与静态网站保持一致,避免规则冲突。

认证流程正确实现

1. 令牌附加的标准方式

Blazor WASM需通过IAccessTokenProvider获取令牌(自动处理缓存与刷新),而非手动读取存储。仅使用Authorization: Bearer <token>头——X-ZUMO-AUTH为旧Azure Mobile Apps专用头,Azure Functions不支持:

private readonly HttpClient _httpClient;
private readonly IAccessTokenProvider _tokenProvider;

public ApiService(HttpClient httpClient, IAccessTokenProvider tokenProvider)
{
    _httpClient = httpClient;
    _tokenProvider = tokenProvider;
}

public async Task<HttpResponseMessage> CallProtectedEndpoint()
{
    var tokenResult = await _tokenProvider.RequestAccessToken(new AccessTokenRequestOptions
    {
        Scopes = new[] { "api://NAME/user_impersonation" }
    });

    if (tokenResult.TryGetToken(out var token))
    {
        _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Value);
        return await _httpClient.GetAsync("https://your-functions-api.azurewebsites.net/api/your-endpoint");
    }
    // 处理令牌获取失败(如引导重新登录)
    return new HttpResponseMessage(HttpStatusCode.Unauthorized);
}

2. 双应用注册的权限配置(若使用)

若客户端与API分别注册应用:

  • API应用注册:暴露user_impersonation权限,应用ID URI设为api://NAME。
  • 客户端应用注册:在API权限中添加API应用的user_impersonation权限,并授予管理员同意(B2B场景必须,否则外部用户无法获取权限)。
  • Blazor的AzureAd配置使用客户端应用的ClientId,而非API应用的。

进程外Azure Functions特殊配置

进程外托管模式下,需在host.json中显式配置认证受众,避免应用服务认证设置未同步:

{
  "version": "2.0",
  "authentication": {
    "azureActiveDirectory": {
      "clientId": "YOUR-FUNCTIONS-APP-REG-CLIENT-ID",
      "allowedAudiences": [
        "api://NAME"
      ]
    }
  }
}

最终验证步骤

  1. 解析accessToken,确认aud为api://NAME、scp包含user_impersonation。
  2. 查看Azure Functions的认证日志(门户->Functions->认证->日志),获取401的具体原因(如受众不匹配、权限不足、令牌过期)。
  3. 确认B2B用户已被邀请至租户,且首次登录时已同意应用权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 11:18:21