Azure Function用DefaultCredentials/托管标识获取JWT访问App Service的scope问题
核心结论
你代码里用的https://management.azure.com/是Azure资源管理(ARM)接口的授权范围,拿到的令牌只能操作Azure控制面资源,根本没法通过目标App Service的鉴权,问题确实出在scope配置上。
正确scope写法
scope取值完全取决于你目标App Service的Azure AD注册配置,分两种通用场景:
- 服务到服务的守护调用(也就是Azure Function用托管标识直接调App Service,没有用户登录上下文):格式固定为
api://<目标App Service关联的Azure AD应用客户端ID>/.default注意:不要直接填App Service的
*.azurewebsites.net域名当scope,Azure AD不会给未在租户内注册的资源签发令牌。如果你的App Service开了内置的Easy Auth认证,系统会自动在Azure AD生成对应服务主体,直接复制这个服务主体的客户端ID填入即可。 - 有用户上下文的委托调用:把上面的
.default替换成你在Azure AD应用暴露API板块配置的具体权限字符串,比如api://<客户端ID>/API.Invoke。
修正后的可用代码
public async Task<string> GetAccessTokenForTargetApp() { // 替换为你目标App Service对应的Azure AD应用客户端ID var targetClientId = "替换为实际目标AAD应用客户端ID"; var requestScopes = new[] { $"api://{targetClientId}/.default" }; // 本地调试时自动读取本地VS、Azure CLI、VS Code的登录账号凭据 // 部署到Azure Function后自动使用配置的系统/用户分配托管标识,不需要改代码 var credential = new DefaultAzureCredential(); var token = await credential.GetTokenAsync(new TokenRequestContext(requestScopes)); return token.Token; }
常见排错点
- scope末尾不要加多余斜杠:比如写成
api://<clientId>/会直接触发AADSTS50001资源不存在错误 - 必须提前配置权限:到目标App Service关联的AAD应用的「API权限」页面,添加Azure Function对应托管标识的应用权限,点击「授予管理员同意」,否则拿到的令牌没有对应权限声明,调用接口会返回403
- 令牌校验:拿到令牌后可以本地解码payload,检查
aud(受众)声明是否和目标App Service配置的合法受众值完全一致,不一致的话100%鉴权失败 - 如果你用的是旧版v1.0 Azure AD端点,scope可以直接填目标应用的应用ID URI,不需要加
.default后缀,目前新创建的Azure AD应用默认走v2.0端点,按上面的格式配置即可。
内容的提问来源于stack exchange,提问作者Simon Price
相关产品推荐
相关产品推荐

