如何从 Key Vault 自动映射 Azure Functions 机密

Posted

技术标签:

【中文标题】如何从 Key Vault 自动映射 Azure Functions 机密【英文标题】:How to map Azure Functions secrets from Key Vault automatically 【发布时间】:2019-03-10 08:25:56 【问题描述】:

我想知道是否可以从从 azure vault 读取的连接字符串中初始化队列触发器甚至 blob 触发器。

现在,我们必须通过刀片属性通过环境设置来设置这些数据连接。但是,我只想使用服务主体来检索 azure key vault 的令牌以获取所有这些连接字符串。

我正在尝试如何在 java 中实现这一点。

谢谢, 德里克

【问题讨论】:

用真正的解决方案编辑了我的帖子 【参考方案1】:

此功能已在此处跟踪并正在进行中:

Feature request: retrieve Azure Functions' secrets from Key Vault Add binding to Key Vault

编辑 28/11/2018:目前处于预览阶段

Simplifying security for serverless and web apps with Azure Functions and App Service

以前的答案 07/10/2018 此解决方案不适用于使用消费计划的触发器。

与此同时,我对您的问题进行了一些研究,如果您使用 Azure Function v2,则可以从密钥保管库中读取配置。

我从 Visual Studio 创建了 Azure Functions v2 (.NET Standard)。

它使用:

NETStandard.Library v2.0.3 Microsoft.NET.Sdk.Functions v1.0.22 Microsoft.Azure.WebJobs v3.0.0 Microsoft.Azure.WebJobs.Extensions.Storage v3.0.0

由于 Azure Functions v2 使用 ASP.NET 核心,我可以参考此链接来配置我的函数应用以使用 Azure Key Vault:

Azure Key Vault configuration provider in ASP.NET Core

    我添加了这个 nuget 包:
Microsoft.Extensions.Configuration.AzureKeyVault

我已将我的应用配置为使用此 nuget 包:

using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System.Linq;

[assembly: WebJobsStartup(typeof(FunctionApp1.WebJobsExtensionStartup), "A Web Jobs Extension Sample")]
namespace FunctionApp1

    public class WebJobsExtensionStartup : IWebJobsStartup
    
        public void Configure(IWebJobsBuilder builder)
        
            // Get the existing configuration
            var serviceProvider = builder.Services.BuildServiceProvider();
            var existingConfig = serviceProvider.GetRequiredService<IConfiguration>();

            // Create a new config based on the existing one and add kv
            var configuration = new ConfigurationBuilder()
                .AddConfiguration(existingConfig)
                .AddAzureKeyVault($"https://existingConfig["keyVaultName"].vault.azure.net/")
                .Build();
        
            // replace the existing configuration
            builder.Services
                .Replace(ServiceDescriptor.Singleton(typeof(IConfiguration), configuration));
        
    

我的 Azure 函数使用 MSI:

我已向我的密钥保管库上的函数应用授予读取/列出机密权限:

我有一个小队列触发函数:

public static class Function2

    [FunctionName("Function2")]
    public static void Run([QueueTrigger("%queueName%", Connection = "queueConnectionString")]string myQueueItem, ILogger log)
    
        log.LogInformation($"C# Queue trigger function processed: myQueueItem");
    

queueNamelocal.settings.json 文件中定义(部署后的应用设置刀片):


  "IsEncrypted": false,
  "Values": 
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet",
    "keyVaultName": "thomastestkv",
    "queueName": "myqueue"
  

queueConnectionString 在我的密钥库中配置:

【讨论】:

谢谢!..我在 java 世界里你...所以我不确定这是否可能。现在现有的sdk github.com/Azure/azure-keyvault-java。您是否知道它们是否提供相同的机制来在加载时配置初始 azure 功能? 哦抱歉不知道你用的是java sdk。不知道 azure 函数运行时是如何工作的... 如果我最终选择了 .netcore 路线,这是了解你的好信息。至少我知道这是可能的,并希望他们在 java 运行时支持它。我相信这篇文章会对其他任何人在未来有所帮助。大多数情况下,他们将使用 .netcore 我会尝试深入研究 java sdk,但我的笔记本电脑上没有任何 java 环境...... 请注意,这种方法在消耗计划中运行时不起作用。由 azure 函数运行的基础设施会监控您的触发器并确定何时运行应用程序,但无法看到服务总线并决定何时扩展应用程序。上面链接的一些 github 问题指向函数中发生的额外工作,以更好地支持这种情况。【参考方案2】:

更新

现在是正式版

这是几天前刚刚发布的预览版

此功能需要系统为您的应用分配托管标识。在这篇文章的后面,我将讨论用户分配的身份,但我们暂时将这些预览分开。

然后,您需要在 Key Vault 上配置访问策略,为您的应用程序授予对机密的 GET 权限。了解如何配置访问策略。

最后,将任何应用程序设置的值设置为以下格式的引用:

@Microsoft.KeyVault(SecretUri=secret_uri_with_version)

其中 secret_uri_with_version 是 Key Vault 中机密的完整 URI。例如,这将类似于:https://myvault.vault.azure.net/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931

Using Keyvault integration within the function runtime

【讨论】:

【参考方案3】:

我只是在下面两个参考文献中用 Java 实现了它。

    https://docs.microsoft.com/en-us/azure/app-service/app-service-key-vault-references

    https://medium.com/statuscode/getting-key-vault-secrets-in-azure-functions-37620fd20a0b

在 java 中使用 System.getenv("SECRET_KEY") 从您的应用设置中读取值。

如果您需要进一步的帮助,我们很乐意提供帮助。

【讨论】:

【参考方案4】:

从 Key Vault 获取应用程序设置 Key Vault 引用功能使您的应用程序可以像使用应用程序设置一样工作,这意味着不需要更改代码。您可以从我们的 Key Vault 参考文档中获取所有详细信息,但我将在此处概述基础知识。

此功能需要系统为您的应用分配托管标识。在这篇文章的后面,我将讨论用户分配的身份,但我们暂时将这些预览分开。

然后,您需要在 Key Vault 上配置访问策略,为您的应用程序授予对机密的 GET 权限。了解如何配置访问策略。

最后,将任何应用程序设置的值设置为以下格式的引用:

@Microsoft.KeyVault(SecretUri=secret_uri_with_version)

其中 secret_uri_with_version 是 Key Vault 中机密的完整 URI。例如,这将类似于:https://myvault.vault.azure.net/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931

就是这样!无需更改您的代码!

对于这个初始预览,您需要明确设置一个秘密版本,因为我们还没有内置的轮换处理。这是我们期待尽快提供的东西。

用户分配的托管身份(公共预览版) 我们对托管身份的现有支持称为系统分配。这个想法是,身份是由平台为特定应用程序创建的,并且与应用程序的生命周期相关联。如果您删除应用程序,则会立即从 Azure Active Directory 中删除该标识。

今天我们正在预览用户分配的身份,这些身份被创建为自己的 Azure 资源,然后分配给给定的应用程序。一个用户分配的身份也可以分配给多个应用程序,一个应用程序可以有多个用户分配的身份。

more details check this

【讨论】:

我们有 2 个用户分配的身份分配给我们的功能用于不同的用途。我看不到如何指定与“@Microsoft.KeyVault(SecretUri=secret_uri_with_version)”一起使用的身份,这失败了。我们可以在运行时使用 Microsoft.Azure.Services.AppAuthentication 正确访问,传入身份的 Id,但不知道如何通过 AppSettings 执行此操作 @MattSanders,我不认为上面的“@Microsoft.KeyVault(SecretUri=secret_uri_with_version)”应该知道身份,身份代表试图访问保险库的应用程序或用户,例如,如果您通过 Web API 应用程序访问密钥,则该应用程序应添加为身份, 如果用户给应用分配了多个身份,这个特性怎么知道使用哪一个? 我有 2 个用户分配的身份,1 个拥有 KeyVault 的权限,另一个没有。如何指定正确的用户分配身份以用于检索机密?我猜这是不可能的,即使您的答案中列出了用户分配的身份,也不支持它们。 @MattSanders,由于我无法在此处附上图片,所以我在下面给出了答案,请检查并分享您的想法,谢谢【参考方案5】:

我已经在上面给出了答案,这个答案是针对@Matt Sanders 的评论, 我只是想解释一下 MSI 如何在 Azure 环境中工作,

"我有 2 个用户分配的身份,1 个拥有 KeyVault 的权限,另一个没有。您如何指定正确的用户分配的身份用于检索机密?我猜这是不可能的和用户分配的身份不受支持,即使它们已列在您的答案中。– Matt Sanders"

当您想使用 Azure Manage Identity Service 时,您的应用程序必须在 Azure AD 中注册,例如,假设有多个用户访问您的 Web 应用程序,并且在您的 Web 应用程序中,您正试图访问 vVault 的机密,在这种情况下,Vault 不关心使用您的应用程序的用户,它关心的是应用程序,

请参考下图,

我如图所示,只有 Azure Function 作为身份添加到库中,其他应用程序没有,

所以任何使用 Azure 功能的人都可以访问 Vault 的机密,根据此示例只有 A 和 B 可以访问机密,

【讨论】:

感谢您尝试对此进行解释,但这并未引用原始答案底部列出的用户分配的托管身份。我没有看到您的原始答案支持这些,您应该从答案中删除关于用户分配的托管身份的底部部分,以避免混淆,因为它与您原本很好的答案无关。

以上是关于如何从 Key Vault 自动映射 Azure Functions 机密的主要内容,如果未能解决你的问题,请参考以下文章

Azure DevOps -> Pipelines -> Library -> 访问 Azure Key Vault -> Key Vault 不允许从所有网络访问

使用 Azure Key Vault 轮换机密

如何使用 Azure Key Vault 中的证书/密钥对使用 Azure Pipelines 构建的代码进行签名?

Azure Key Vault 从 VMSS 实例获取机密

Azure Key Vault 使用Azure Portal创建和查看Azure Key Vault

从 Azure Functions 访问 Azure Key Vault 时访问被拒绝