【问题标题】:KeyVault integration with Azure Functions (powershell runtime) not workingKeyVault 与 Azure Functions(powershell 运行时)的集成不起作用
【发布时间】:2019-09-02 08:54:04
【问题描述】:

我正在尝试关注这个https://azure.microsoft.com/en-us/blog/simplifying-security-for-serverless-and-web-apps-with-azure-functions-and-app-service/,以便在使用 azure 函数时从我的密钥库中安全地获取我的秘密。

我的密钥保管库有一个访问策略,允许通过函数应用的SYSTEM MANAGED IDENTITY 获取机密。

这是高级编辑器中显示的相关应用设置(slotSetting 是真还是假都没有关系,已经尝试过了。不知道它有什么作用)

{
    "name": "ultrasecret",
    "value": "@Microsoft.KeyVault(SecretUri=https://<vault-name>.vault.azure.net/secrets/<secret-name>/<version>)",
    "slotSetting": true
}

这是我唯一的函数的脚手架版本,请查看下面的 IF 块,了解我通过暴露密钥库秘密的环境变量间接查询密钥库。

using namespace System.Net

# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)

# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."

# Interact with query parameters or the body of the request.
$name = $Request.Query.Name
if (-not $name) {
    $name = $Request.Body.Name
}

if ($name) {
    $status = [HttpStatusCode]::OK
    $secret = $env:ultrasecret
    $body = "Hello $name $secret"
}
else {
    $status = [HttpStatusCode]::BadRequest
    $body = "Please pass a name on the query string or in the request body."
}

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = $status
    Body = $body
})

当我发出 GET 请求时

https://&lt;function-app-name&gt;.azurewebsites.net/api/HttpTrigger1?name=john

这是返回的内容

Hello john @Microsoft.KeyVault(SecretUri=https://&lt;vault-name&gt;.vault.azure.net/secrets/&lt;secret-name&gt;/&lt;version&gt;)

所以基本上我返回的是文字设置的值,而不是秘密。这是因为 Powershell 支持处于预览状态吗?其他人搞定了吗?

非常感谢任何帮助。

【问题讨论】:

  • 看来我不是唯一的......这是一个github问题github.com/MicrosoftDocs/azure-docs/issues/33480
  • 我可以进一步确认它与 MSI 本身无关。我能够成功地对密钥库 API 进行手动 REST 调用(从 az 函数中)并查询密钥并在我的函数中使用它。因此,我可能需要(作为一种解决方法)手动在环境变量中设置我的秘密,而不是使用官方方式。

标签: powershell azure-functions azure-keyvault azure-managed-identity


【解决方案1】:

如果要在 Azure Function 中访问密钥保管库机密,有两种选择。

  • 设置为环境变量

如果要将 Azure Key Vault 机密设置为环境变量,可以使用 Azure CLI 完成。更多详情请参考https://docs.microsoft.com/en-us/azure/azure-functions/functions-how-to-use-azure-function-app-settings

az functionapp config appsettings set -n testfun08 -g testfun07 --settings "Secret1=@Microsoft.KeyVault(SecretUri=<$secretId>)"

  • 使用 Azure key Vault REST API

如果您想使用 Azure Key Vault REST API 获取 Azure 密钥保管库的值,请按照以下详细步骤操作。

  1. Configure MSI
  2. Configure Azure Key Vault access policy
    Connect-AzAccount

    $app=Get-AzADServicePrincipal -DisplayName "your function app name"

    Set-AzKeyVaultAccessPolicy -VaultName "your key vault name" -ResourceGroupName "your group name" -ObjectId $app.Id -PermissionsToSecrets list, get
  1. 代码
using namespace System.Net

# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)

# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."

# Interact with query parameters or the body of the request.
$name = $Request.Query.Name
if (-not $name) {
    $name = $Request.Body.Name
}

if ($name) {
# get access token with MSI. For more details, please refer to https://docs.microsoft.com/en-us/azure/app-service/overview-managed-identity#rest-protocol-examples
    $tokenAuthURI = $Env:MSI_ENDPOINT +"?resource=https://vault.azure.net&api-version=2017-09-01"
   $tokenResponse = Invoke-RestMethod -Method Get -Headers @{"Secret"="$env:MSI_SECRET"} -Uri $tokenAuthURI
$accessToken = $tokenResponse.access_token
# get secret value
$headers = @{ 'Authorization' = "Bearer $accessToken" }
$queryUrl = "the url of secret" + "?api-version=7.0"

$keyResponse = Invoke-RestMethod -Method GET -Uri $queryUrl -Headers $headers
$value= $keyResponse.value
Write-Host "$vaule"  
    $status = [HttpStatusCode]::OK
    $body = "Hello $name $value"
}
else {
    $status = [HttpStatusCode]::BadRequest
    $body = "Please pass a name on the query string or in the request body."
}

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = $status
    Body = $body
})

更多详情请参考Key Vault returns 401 with access token (MSI PowerShell Function App)

更新

如何检查我们是否通过 Kudu 成功设置了应用设置

【讨论】:

  • 谢谢。我尝试通过 az cli 进行设置。但是我必须输入 az functionapp config appsettings set -n testfun08 -g testfun07 --settings "Secret1=@Microsoft.KeyVault(SecretUri=^^)"
  • 仍然,我不知道它为什么手动/REST 工作,但是通过 app_settings 完成时它不会(这应该是官方和记录的方式)
  • 你是直接通过Azure Portal添加的吗?
  • 通过门户、az cli 和模板部署 (terraform) 都不适合我。只有手动调用密钥保管库的其余 API 才有效。但是我无法将其保留为 env 变量,因为函数应用程序只允许设置进程范围的 env 变量,而不是用户范围和机器范围。即使是高级计划......所以那里出现了新问题
  • 能否请您检查您是否已成功设置应用程序设置?关于如何做到这一点,请参阅我的更新。
【解决方案2】:

我在与您的代码相似的代码上遇到了同样的错误,我发现解决权限错误可以解决问题。

在 Platform features --> Configuration 下查看您的设置的源列并检查它是否有效。您可以编辑该项目以获取该条目的详细错误消息。

有效

错误

在我的情况下,函数应用没有访问密钥库的权限。

使用 Azure 门户打开函数应用刀片

  1. 选择平台功能选项卡。
  2. 选择身份。
  3. 在“系统分配”选项卡中,将“状态”切换为“开启”。
  4. 点击保存。
  5. 将对象 ID 复制到剪贴板。

导航到密钥保管库

  1. 选择访问策略。
  2. 添加访问策略
  3. 在秘密下,选择 GET、LIST。
  4. 在选择主体下,粘贴对象 ID。
  5. 选择您的函数应用名称。
  6. 点击添加。
  7. 点击保存。

返回到您的函数应用并在平台功能 --> 配置下验证引用是否有效。

见:Adding a system-assigned identity

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-17
    • 1970-01-01
    • 2022-01-03
    相关资源
    最近更新 更多