如何在 Web 应用程序(具有 user-assigned 托管身份)Kudu powershell 环境下获取 Key Vault Secret?

How to get Key Vault Secret under Web App's (with a user-assigned managed identity) Kudu powershell environment?

如果我有一个具有 system-assigned 托管身份的 Web 应用程序,并且该 Web 应用程序已添加到 Key Vault 的访问策略中,我可以使用以下代码从 Key Vault 中获取秘密值捻角羚 powershell 环境:

function GetSecret {
    param (
                [parameter(Mandatory=$True, Position=1)] [String] $keyVaultSecretUri
            )
    $apiVersion="2017-09-01"
    $resourceURI = "https://vault.azure.net"
    $tokenResponse = Invoke-RestMethod `
                    -Method Get `
                    -Headers @{"Secret"="$env:MSI_SECRET";"Content-Type"="application/json"} `
                    -Uri "${env:MSI_ENDPOINT}?resource=${resourceURI}&api-version=${apiVersion}"
    $accessToken = $tokenResponse.access_token
    $headers = @{'Authorization'="Bearer $accessToken"}

    $keyVaultApiVersion="7.1"
    $secret=Invoke-RestMethod -Method Get -Headers $headers -Uri "${keyVaultSecretUri}?api-version=${keyVaultApiVersion}"
    return $secret
}
GetSecret -keyVaultSecretUri $SecreteUri

但是如果我给网络应用程序一个 user-assigned 托管身份(没有 system-assigned 托管身份)并将该托管身份添加到 Key Vault 的访问策略(具有足够的权限),上面的代码没用。

实际上,即使是以下三行也会出现运行时异常:

$apiVersion="2017-09-01"
$resourceURI = "https://vault.azure.net"
$tokenResponse = Invoke-RestMethod `
                    -Method Get `
                    -Headers @{"Secret"="$env:MSI_SECRET";"Content-Type"="application/json"} `
                    -Uri "${env:MSI_ENDPOINT}?resource=${resourceURI}&api-version=${apiVersion}"

例外情况是(CorrelationId 被隐藏):

Invoke-RestMethod : {"StatusCode":400,"Message":"No MSI found for specified 
ClientId/ResourceId.","CorrelationId":"0000000-0000-0000-0000-000000000000"}
At line:1 char:18
+ $tokenResponse = Invoke-RestMethod `
+                  ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:Htt 
   pWebRequest) [Invoke-RestMethod], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShe 
   ll.Commands.InvokeRestMethodCommand

那么如何在 Web 应用程序(具有 user-assigned 托管身份)Kudu powershell 环境下获取 Key Vault Secret?

(可能 user-assigned 身份网络应用程序的 Headers 是错误的)

PS:这个答案 没有解决我的问题。

其实我刚才写了一篇关于这个话题的文章:https://joonasw.net/view/get-managed-identity-access-token-in-azure-app-service-through-kudu。 我 link 到 Managed Identity 使用的 REST 协议的文档:https://docs.microsoft.com/en-us/azure/app-service/overview-managed-identity?tabs=dotnet#using-the-rest-protocol.

如果您使用用户分配的身份,则必须确定要使用的身份。 由于应用服务等可以有多个用户分配的身份。 在文档中,他们提供了以下选项:

如果我没记错的话,你只需要指定其中一项即可。

测试了这个脚本并获得了用户分配身份的令牌:

$resource = "https://vault.azure.net"

$clientId = "00000000-0000-0000-0000-000000000000"

$endpoint = $env:IDENTITY_ENDPOINT
$header = $env:IDENTITY_HEADER
$apiVersion = "2019-08-01"

$headers = @{ 'X-Identity-Header' = $header }

$url = "$($endpoint)?api-version=$apiVersion&resource=$resource&client_id=$clientId"

$response = Invoke-RestMethod -Method Get -Uri $url -Headers $headers
$response.access_token