如何在 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
如果我有一个具有 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