跨订阅从App Service访问Azure KeyVault遇S2S12005授权错误
问题详情
跨订阅的App Service访问Azure KeyVault时,已为托管标识的主体ID配置了密钥Get权限,但收到如下错误:
{"error":{"code":"Unauthorized","message":"[BearerReadAccessTokenFailed] Error validating token: 'S2S12005'."}
测试用PowerShell代码如下:
$resource = "https://{keyVaultName}.vault.azure.net/" $endpoint = $env:IDENTITY_ENDPOINT $header = $env:IDENTITY_HEADER $apiVersion = "2019-08-01" $headers = @{ 'X-Identity-Header' = $header } $url = "$($endpoint)?api-version=$apiVersion&resource=$resource" $response = Invoke-RestMethod -Method Get -Uri $url -Headers $headers $response.access_token Invoke-RestMethod -Uri $resource/secrets/ClientGUID?api-version=$apiVersion -Method GET -Headers @{Authorization="Bearer $response.access_token"}
排查与修复步骤
核对托管标识主体ID的正确性
确认App Service的系统/用户分配托管标识的对象ID,与KeyVault访问策略中配置的主体ID完全一致,避免出现ID复制错误(如混淆对象ID与应用ID、末尾带空格等)。验证KeyVault访问策略权限
确保访问策略中明确授予了目标密钥的Get权限,可先尝试授予所有密钥的Get权限进行测试;同时确认策略未设置额外的限制条件(如IP范围、虚拟网络)导致权限无法生效。检查令牌受众(Audience)匹配性
解析获取到的access_token,确认aud字段值为https://vault.azure.net(注意不要包含末尾斜杠)。当前代码中$resource带了末尾斜杠,可能导致令牌受众不匹配,修改为https://{keyVaultName}.vault.azure.net(去掉斜杠)后重新请求令牌。验证托管标识跨订阅访问有效性
确认App Service与KeyVault处于同一Azure AD租户(跨租户场景需额外配置来宾权限,S2S12005错误更常见于租户内跨订阅),托管标识的主体ID在KeyVault所在租户中处于有效状态。用Azure PowerShell模块简化测试
在App Service的Kudu控制台执行以下代码,排除手动令牌请求的问题:Connect-AzAccount -Identity Get-AzKeyVaultSecret -VaultName "{keyVaultName}" -Name "ClientGUID"若此命令成功,说明托管标识权限正常,问题出在手动请求令牌的代码逻辑;若失败,需重新检查访问策略与托管标识配置。
检查KeyVault防火墙与网络设置
若KeyVault启用了防火墙,需将App Service的出站IP地址加入允许列表,或开启"允许受信任的Microsoft服务访问此密钥保管库"选项(跨订阅App Service默认不在信任列表中,需手动配置)。
内容的提问来源于stack exchange,提问作者Ivalberto

