如何利用托管身份调用受Azure AD保护的Azure Function API?
问题解答:用Azure App Service托管身份访问受Azure AD保护的Function App API
核心结论
完全可以通过系统分配或用户分配的托管身份获取访问令牌,无需存储client-secret,避免密钥轮换的麻烦。你遇到的问题主要是托管身份的权限配置方式不对,以及门户操作路径的误区。
关键配置步骤
1. 确认Function App对应的API应用注册
你的Function App启用Azure AD身份验证时,会关联一个应用注册(记为「API应用注册」)。先找到这个应用注册的:
- 客户端ID(Client ID)
- 标识符URI(Identifier URI)(通常是
api://<client-id>格式)
2. 给API应用注册添加应用角色(可选但推荐)
如果还没创建应用角色,在API应用注册的「应用角色」页面添加一个角色(比如FunctionAPI.Access),设置允许的成员类型为「应用程序」。
3. 给托管身份分配API访问权限
因为托管身份本质是Azure AD中的服务主体,无法直接在API应用注册的「授权客户端应用」列表中选中(该列表仅显示显式创建的应用注册),需要通过以下方式配置:
方式一:Azure门户操作
- 进入Azure门户的「企业应用」,搜索你的App Service托管身份名称(系统分配的托管身份名称就是App Service的名称;用户分配的托管身份是你创建的名称)。
- 进入该托管身份的「权限」页面,点击「添加权限」。
- 选择「我的API」,找到你的API应用注册,勾选之前创建的应用角色(或选择「.default」权限),然后点击「添加权限」。
- 最后点击「授予管理员同意」(需要Azure AD管理员权限)。
方式二:Azure CLI命令
# 1. 获取系统分配托管身份的Object ID az webapp identity show --name <你的App Service名称> --resource-group <资源组名称> # 2. 给托管身份分配API应用注册的应用角色 # 替换<api-app-client-id>为API应用注册的Client ID,<app-role-id>为应用角色的ID az ad app permission add --id <api-app-client-id> --api-permissions <app-role-id>=Role --api <api-app-client-id> az ad app permission grant --id <托管身份Object ID> --api <api-app-client-id>
4. 验证代码配置
你的代码本身没问题,但要确保getToken的scope是API应用注册的标识符URI加上/.default,比如:
const credential = new DefaultAzureCredential(); // 替换为你的API应用注册的标识符URI + /.default const token = await credential.getToken("api://0axxxxxxxxxxxxxxxxxxx/.default"); console.log("token ->> ", token.token);
部署后无法获取令牌的排查点
- 确认托管身份权限已生效:等待5-10分钟让Azure AD权限同步,然后重启App Service。
- 检查DefaultAzureCredential的工作逻辑:在App Service环境中,
DefaultAzureCredential会自动优先使用系统分配的托管身份;如果是用户分配的托管身份,需要在初始化时指定managedIdentityClientId:const credential = new DefaultAzureCredential({ managedIdentityClientId: "<用户分配托管身份的Client ID>" }); - 检查Function App的Azure AD身份验证设置:确保其「允许的令牌受众」包含API应用注册的标识符URI,并且没有限制特定客户端。
内容的提问来源于stack exchange,提问作者codeKnightly
相关产品推荐
相关产品推荐

