Azure Key Vault – 从 Functions 获取秘钥(Python / Nodejs)

只需要一个选项:目标

使用Azure SDK for Python,从Azure Functions(触发器:EventGrid)中获取Azure Key Vault的秘密

生成 Azure Key Vault 的秘钥

    1. 在Azure门户中,转到密钥容器

 

    1. 点击“生成/导入”选项

 

    输入任意名称和值,然后点击“创建”
2.png

将对 Key Vault 的访问权限授予应用程序。

公式文件

    • App Service と Azure Functions の Key Vault 参照を使用する

 

    App Service と Azure Functions でマネージド ID を使用する方法

创建Azure Functions的系统分配的托管ID。

    1. 在Azure门户中,转到函数应用

 

    1. 点击ID

 

    在系统分配标签页中将状态更改为开启
3.png

创建 Key Vault 的访问策略

1.在 Azure 门户中,导航到密钥容器。
2.点击访问策略,然后点击+添加访问策略。

4.png

3.勾选所需操作,从秘密授权许可中。
4.点击选择主体右侧的链接。
5.搜索、选择并点击添加之前分配的Azure Functions项目名称。

6.png

实施

蓝色功能(使用Python语言)

import json
import logging

import azure.functions as func
from azure.keyvault.secrets import SecretClient
from azure.identity import DefaultAzureCredential

def main(event: func.EventGridEvent):
  keyVaultName = "xxxxx"  # キーコンテナ名
  KVUri = f"https://{keyVaultName}.vault.azure.net"

  credential = DefaultAzureCredential() # 資格情報の取得
  client = SecretClient(vault_url=KVUri, credential=credential)

  secretName = "yyyyy"  # シークレット名
  retrieved_secret = client.get_secret(secretName)
  logging.info(f"Your secret is : '{retrieved_secret.value}'.")

默认的Azure凭证会依次检查环境变量、托管标识、Visual Studio Code中注册的帐户信息等,以获取凭证信息。在此情况下,凭证将从托管标识获取。

结果:秘密获取失败。

在使用Azure Functions和Python的情况下,无法获取密钥。
根据日志显示401错误,认证失败。
可以看出,ManagedIdentityCredential正在使用应用服务的托管标识。
*原因未知:2021/05/05

[Information]   Executing 'Functions.EventGridTrigger-key-vault' (Reason='EventGrid trigger fired at 2021-05-03T06:03:44.8917058+00:00', Id=4c
[Verbose]   Sending invocation id:4c4b8da5-
[Verbose]   Posting invocation id:4c4b8da5- on workerId:7461e294-
[Information]   ManagedIdentityCredential will use App Service managed identity
[Information]   send request
[Information]   Request URL: 'https://xxxxxx.vault.azure.net/secrets/xxxxx/?api-version=REDACTED'
[Information]   Request method: 'GET'
[Information]   Request headers:
[Information]       'Accept': 'application/json'
[Information]       'x-ms-client-request-id': '5193e'
[Information]       'User-Agent': 'azsdk-python-keyvault-secrets/4.2.0 Python/3.8.9 (Linux-5.4.81-microsoft-standard-x86_64-with-glibc2.2.5)'
[Information]       'Content-Length': '0'
[Information]   No body was attached to the request
[Information]   Response status: 401
[Information]   Response headers:
[Information]       'Cache-Control': 'no-cache'
[Information]       'Pragma': 'no-cache'
[Information]       'Content-Length': '87'
[Information]       'Content-Type': 'application/json; charset=utf-8'
[Information]       'Expires': '-1'
[Information]   Response status: 200
[Information]   Executing 'Functions.EventGridTrigger-key-vault' (Reason='EventGrid trigger fired at 2021-05-03T06:03:44.8917058+00:00', Id=4c4b8da

[2021/05/19 追加] 找到解決方法。

我的 Functions 通过与 Azure API Management 的连接,成功获取到了密钥,并在响应中返回了该密钥,一切都顺利进行。

8.png

有关与Azure API Management的集成方法,请参阅以下内容:
Azure API Management – 从Swagger导入API,与Functions进行集成

导致的原因可以是多种多样的。

7.png

本地执行(使用Python)

结果:成功获取了秘密。

如果是在本地执行且使用Python,获取凭据将没有任何问题。以下是执行时的日志:
如果在本地执行,将从AzureCLI中注册的帐户信息中获取凭据,因此环境变量→托管ID→在Visual StudioCode中获取凭据将失败。

EnvironmentCredential.get_token failed: EnvironmentCredential authentication unavailable. Environment variables are not fully configured.
ManagedIdentityCredential.get_token failed: ManagedIdentityCredential authentication unavailable, no managed identity endpoint found.
SharedTokenCacheCredential.get_token failed: SharedTokenCacheCredential authentication unavailable. No accounts were found in the cache.
Your secret is '1234567789'.

Azure Functions(Nodejs):蓝色函数(Node.js)

const { DefaultAzureCredential } = require("@azure/identity");
const { SecretClient } = require("@azure/keyvault-secrets");

module.exports = async function (context, eventGridEvent) {

    const keyVaultName = "xxxxx";
    const KVUri = "https://" + keyVaultName + ".vault.azure.net";
    const secretName = "yyyyy";

    const credential = new DefaultAzureCredential();
    const client = new SecretClient(KVUri, credential);

    const retrievedSecret = await client.getSecret(secretName);
    context.log("Your secret is '" + retrievedSecret.value + "'.");
};

结果:成功获取秘密信息

Azure Functions和Node.js的情况下,成功获取到了秘密,没有问题。
以下是运行时的日志。

[Information] Executing 'Functions.EventGridTrigger-node-key-vault' (Reason='EventGrid trigger fired at 2021-05-04T23:24:06.05164
[Information] Your secret is '1234567789'.
[Information] Executed 'Functions.EventGridTrigger-node-key-vault' (Succeeded, Id=788e3f19, Duration=