如何使用托管标识实现Azure Web App到APIM的Entra ID身份验证?
解决方案:解决APIM中Entra ID验证与托管标识认证的冲突问题
核心问题分析
你的怀疑方向存在偏差,validate-azure-ad-token和set-header本身不存在冲突——因为入站策略按顺序执行:先验证Web App传入的Authorization头令牌,验证通过后再替换为APIM托管标识的令牌转发给AOAI。验证失败的根源大概率是受众配置错误或策略顺序不合理。
具体修复步骤
1. 修正validate-azure-ad-token的受众配置
Web App获取的Entra ID令牌,其受众(aud)必须匹配APIM API的应用ID URI,而非APIM主机名:
- 登录Azure门户,进入目标APIM实例 → 对应API → 设置 → 复制「应用ID URI」(格式通常为
https://<你的APIM名称>.azure-api.net/<API名称>或自定义值) - 修改策略中的受众配置:
<validate-azure-ad-token tenant-id="{{tenantid}}" header-name="Authorization" authentication-endpoint="https://login.microsoftonline.com" failed-validation-httpcode="401" failed-validation-error-message="Invalid token"> <client-application-ids> <application-id>web-app-managed-id-app-id</application-id> </client-application-ids> <audiences> <audience>https://your-apim-name.azure-api.net/your-api-name</audience> <!-- 可选:添加APIM服务主体ID,支持门户测试面板验证 --> <audience>your-apim-service-principal-id</audience> </audiences> </validate-azure-ad-token>
2. 确保策略执行顺序正确
入站策略必须遵循「先验证入站令牌,再获取并替换转发令牌」的顺序:
<!-- 第一步:验证Web App传入的Entra ID令牌 --> <validate-azure-ad-token tenant-id="{{tenantid}}" header-name="Authorization" authentication-endpoint="https://login.microsoftonline.com" failed-validation-httpcode="401" failed-validation-error-message="Invalid token"> <client-application-ids> <application-id>web-app-managed-id-app-id</application-id> </client-application-ids> <audiences> <audience>https://your-apim-name.azure-api.net/your-api-name</audience> </audiences> </validate-azure-ad-token> <!-- 第二步:获取APIM托管标识的令牌,替换Authorization头转发给AOAI --> <authentication-managed-identity resource="https://cognitiveservices.azure.com" client-id="{{MANAGED-IDENTITY-CLIENT-ID}}" output-token-variable-name="msi-access-token" ignore-error="false" /> <set-header name="Authorization" exists-action="override"> <value>@("Bearer " + (string)context.Variables["msi-access-token"])</value> </set-header>
3. 配置Web App的Python客户端
使用AzureOpenAI/AsyncAzureOpenAI时,指定APIM端点并让客户端自动获取托管标识令牌:
from azure.identity import DefaultAzureCredential from openai import AzureOpenAI, AsyncAzureOpenAI # 同步客户端 client = AzureOpenAI( azure_endpoint="https://your-apim-name.azure-api.net/your-api-name", api_version="2024-02-15-preview", credential=DefaultAzureCredential() ) # 异步客户端 async_client = AsyncAzureOpenAI( azure_endpoint="https://your-apim-name.azure-api.net/your-api-name", api_version="2024-02-15-preview", credential=DefaultAzureCredential() )
注:
DefaultAzureCredential会自动调用Web App的系统托管标识获取令牌,无需手动处理。
4. 门户测试面板的验证修复
若要使用APIM门户测试面板,需获取受众为APIM应用ID URI的令牌:
- 打开Azure Cloud Shell,执行以下命令获取测试令牌:
az account get-access-token --resource "https://your-apim-name.azure-api.net/your-api-name" --query "accessToken" --output tsv - 在测试面板的
Authorization头中填入Bearer <获取到的令牌>即可通过验证。
关键注意事项
- 确保Web App的系统托管标识已被授予APIM API的访问权限(可在APIM的「访问控制(IAM)」中添加「API管理服务读者」或自定义角色)。
- 确认APIM的托管标识已被授予AOAI的「认知服务用户」角色,确保能正常获取令牌访问AOAI。
内容的提问来源于stack exchange,提问作者Angrydot
相关产品推荐
相关产品推荐

