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

Azure Function访问Blob Storage私有托管站点认证失败问题

核心错误原因

你请求Blob Storage时携带的Bearer令牌不符合服务鉴权要求:
从请求头x-ms-token-aad-access-token获取的令牌,是AAD颁发给你的Azure Function应用的用户登录令牌,该令牌的受众(aud声明)为你的Function关联的App Registration标识,并非Blob Storage服务认可的资源受众,因此存储服务会直接返回签名/鉴权失败错误。

修复步骤

1. 调整令牌获取逻辑,使用OBO流换取存储服务的有效令牌

不能直接透传用户访问Function的令牌去请求Blob,需要通过代表用户(On-Behalf-Of, OBO) 流,用当前用户的登录令牌,向AAD申请颁发给Blob Storage服务的访问令牌:

  • 到你关联的App Registration配置页,添加API权限:选择Azure Storage服务下的user_impersonation委托权限,完成租户管理员同意配置。
  • 为App Registration生成客户端密钥(或配置证书认证),用于OBO流的服务端认证。
  • 替换原有直接读取请求头令牌的逻辑,参考如下代码换取存储服务令牌:
// 需提前在Function项目中引入Microsoft.Identity.Client包
// 获取用户访问Function时携带的原始令牌
var userToken = req.Headers
    .FirstOrDefault(p => p.Key.Equals("x-ms-token-aad-access-token", StringComparison.OrdinalIgnoreCase))
    .Value.FirstOrDefault();

// 构建机密客户端用于OBO流请求
var cca = ConfidentialClientApplicationBuilder
    .Create("你的App Registration客户端ID")
    .WithClientSecret("你生成的App Registration客户端密钥")
    .WithTenantId("你的AAD租户ID")
    .Build();

// 换取受众为Blob Storage的访问令牌
var tokenResult = await cca.AcquireTokenOnBehalfOf(
    scopes: new[] { "https://storage.azure.com/user_impersonation" },
    userAssertion: new UserAssertion(userToken)
).ExecuteAsync();

// 后续请求Blob时使用tokenResult.AccessToken作为Bearer令牌即可
var validBlobToken = tokenResult.AccessToken;
  • 你原有代码中的RefreshToken逻辑也需要同步调整:令牌过期时重新走OBO流换取新的存储令牌,不要直接刷新原有的Function访问令牌。

2. 修正存储账号的权限配置

  • 移除你之前在存储允许令牌受众中配置的App ID,该配置不适用于当前场景。
  • 为需要访问HTML文件的用户/用户组分配存储账号的对应角色:仅需读取权限的话,分配存储Blob数据读者角色即可,作用域选择你存放HTML文件的容器或整个存储账号。

3. 可选优化

  • 建议使用官方Blob存储SDK替代原生HttpClient发起请求,不需要手动维护x-ms-version头、处理请求重试和内容解析,减少兼容问题。
  • 你当前代码中使用的2017-11-09存储服务版本过旧,即使继续用HttpClient请求,也建议升级到2020年后的稳定服务版本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 22:15:48