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

如何将已有的Azure Function令牌用作凭据访问资源?

问题:Azure函数应用中使用已认证用户身份访问存储资源

我有启用Active Directory认证的Azure Linux函数应用,以及启用Active Directory认证的Azure静态Web应用。静态Web应用生成的Bearer令牌可正常调用函数,但在函数体内,无法通过DefaultAzureCredential识别已认证用户信息,进而无法使用用户身份读写存储等资源。

现有代码

函数触发代码

const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
  // req.user 内容如下

  await readFile(...)

  context.res = {
    status: 200,
    body: {
      apps
    }
  };
};

export default httpTrigger;

req.user 已认证信息(精简)

{
  "type": "AppService",
  "id": "...",
  "username": "...@....com",
  "identityProvider": "aad",
  "claimsPrincipalData": {
    "auth_typ": "aad",
    "claims": [
      ...
    ],
    "name_typ": "...",
    "role_typ": "..."
  }
}

期望的Blob读取代码

const readFile = async (...) => {
  const credential = new DefaultAzureCredential()

  const blobServiceClient = new BlobServiceClient(
    `https://${accountName}.blob.core.windows.net`,
    credential
  );

  const containerClient = blobServiceClient.getContainerClient(containerName);
  const blobClient = containerClient.getBlobClient(blobName);

  const downloadBlockBlobResponse = await blobClient.download();

  ...
}

遇到的错误

Exception: ChainedTokenCredential authentication failed.
CredentialUnavailableError: EnvironmentCredential is unavailable. No underlying credential could be used. 

解决方案

1. 获取用户的访问令牌

DefaultAzureCredential是用于获取函数应用自身的托管标识,无法直接关联当前请求的用户身份。需要从请求头中提取用户的原始访问令牌:

  • 从Authorization头提取:去掉Bearer 前缀,获得令牌内容
  • 若函数应用认证设置开启了令牌存储,可直接从x-ms-token-aad-access-token请求头读取令牌

2. 使用AccessTokenCredential创建用户凭据

通过@azure/identity包中的AccessTokenCredential,用用户令牌创建可用于Azure SDK的凭据,代表用户身份访问资源。

修改后的完整代码

函数触发逻辑

const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
  // 提取用户访问令牌
  const accessToken = req.headers["x-ms-token-aad-access-token"] || 
                     req.headers.authorization?.replace("Bearer ", "");

  if (!accessToken) {
    context.res = { status: 401, body: "无法获取用户认证令牌" };
    return;
  }

  await readFile(accessToken, accountName, containerName, blobName);

  context.res = {
    status: 200,
    body: { apps }
  };
};

export default httpTrigger;

Blob读取逻辑

import { AccessTokenCredential } from "@azure/identity";
import { BlobServiceClient } from "@azure/storage-blob";

const readFile = async (accessToken: string, accountName: string, containerName: string, blobName: string) => {
  // 基于用户令牌创建凭据
  const credential = new AccessTokenCredential(accessToken);

  const blobServiceClient = new BlobServiceClient(
    `https://${accountName}.blob.core.windows.net`,
    credential
  );

  const containerClient = blobServiceClient.getContainerClient(containerName);
  const blobClient = containerClient.getBlobClient(blobName);

  const downloadBlockBlobResponse = await blobClient.download();

  // 后续数据处理逻辑
};

3. 权限配置

  • 确保已给AD用户分配对应存储资源的RBAC角色(如存储Blob数据读者、存储Blob数据参与者)
  • 确保静态Web应用请求的令牌包含目标资源的scope(如https://storage.azure.com/.default)

额外注意

  • 需安装依赖包:npm install @azure/identity @azure/storage-blob
  • 在Azure门户的函数应用→认证→身份提供者→Azure AD设置中,勾选“将访问令牌存储在请求头中”,确保x-ms-token-aad-access-token头存在

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 19:57:45