【问题标题】:Azure Function BlobTrigger connection from KeyVault来自 KeyVault 的 Azure Function BlobTrigger 连接
【发布时间】:2018-04-29 15:28:48
【问题描述】:

总结:我可以使用 KeyVault 将连接字符串提供给 Blob 存储绑定吗?

我最近将我的所有连接字符串和机密从 Azure Function 应用设置中移出到 KeyVault 中。这包括我引用的各种存储帐户的连接字符串。我现在正在处理 Azure Blob 存储绑定,但似乎 (per the docs) 引用连接字符串的所有方法都解析为应用级别设置。

我希望不必将这个秘密放在两个不同的地方。有没有办法指定存储帐户连接字符串ala KeyVault?

【问题讨论】:

标签: azure-functions azure-keyvault


【解决方案1】:

我可能处于不同的切线,但我相信我同意@ThatCreole 的观点,这是一种痛苦。集中配置和从已部署代码中删除机密不仅仅是在 CI/CD 管道中替换它的位置。如果文件系统受到破坏,访问配置文件会进一步破坏您的基础设施。借助 Azure,我们能够使用托管服务标识,它在系统运行和天蓝色活动目录的基础硬件上创建信任。这样就无需在任何时候将任何机密存储在配置中,包括访问 Key Vault 的机密。 Azure 函数可以利用这一点,但这仅在应用程序的启动/运行时有帮助。触发功能仍然依赖于触发,甚至达到该点,这会导致少量曝光表面。

我唯一能做的就是为触发器创建一个 RBAC,该触发器的权限集极其有限。将其添加为函数中的触发器,然后让函数在启动时通过密钥库加载扩展权限 RBAC。这是一个不幸的解决方法,但我看不到另一种方法来做到这一点,同时保持我们系统的安全性。

【讨论】:

    【解决方案2】:

    我创建了一个 nuget 包,它将 Azure KeyVault 集成到 Azure Functions 中,并支持连接字符串等。这实际上现在可以使用 Azure Function v2,因为它在内部使用 Microsoft.Extensions.Configuration。我们可以利用它并使用 Azure Key Vault 扩展配置。因此,您需要创建一个 WebJobsStartup 类,从 WebjobsBuuilder 服务提供商处获取IConfiguration,并使用 Azure KeyVault 重新创建它。

    static IWebJobsBuilder AddAzureKeyVault(this IWebJobsBuilder builder, 
        Func<ConfigurationBuilder, IKeyVaultClient> configure)
    {
        var configurationBuilder = new ConfigurationBuilder();
        var descriptor = builder.Services.FirstOrDefault(d => d.ServiceType == typeof(IConfiguration));
        if (descriptor?.ImplementationInstance is IConfigurationRoot configuration)
        {
            configurationBuilder.AddConfiguration(configuration);
        }
    
        configurationBuilder.AddAzureKeyVault(....);
    
        var config = configurationBuilder.Build();
        builder.Services.Replace(ServiceDescriptor.Singleton(typeof(IConfiguration), config));
        return builder;
    }
    

    您可以在 https://github.com/BorisWilhelms/azure-function-keyvault 上找到它的来源。

    【讨论】:

    • 从.net core 3.1(和可能的.net core 3.0)开始,这将不再起作用,因为descriptor?.ImplementationInstance 将为空。在 dotnet/extensions link 中打开的问题
    【解决方案3】:

    如果您询问是否可以执行以下操作:

    [FunctionName("ResizeImage")]
    public static void Run(
       [BlobTrigger("sample-images/{name}", Connection = "StorageConnectionAppSetting")] Stream image, 
       [Blob("sample-images-md/{name}", FileAccess.Write)] Stream imageSmall)
    {
       ....
    }
    

    然后存储 StorageConnectionAppSetting 使其指向 KeyVault 实例(而不是容易访问的连接字符串),那么恐怕目前还不可能。

    当然也可以像这样手动获取连接字符串:

    var azureServiceTokenProvider = new AzureServiceTokenProvider();
    var kvClient = new KeyVaultClient(new  KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback), client);                
    string blobConectionString = (await 
    kvClient.GetSecretAsync("some"secret")).Value;
    

    然后“手动”连接到 Blob(因此不会使用绑定),但我想这对你来说可能是不行的。

    另一个问题是 - 将连接字符串存储在 KV 中的原因是什么?是不是因为存储在功能应用的应用设置里,怕别人看?还是因为您不想将其存储在 CI/CD 管道中?

    【讨论】:

    • 谢谢。我的推理是后者。我现在使用 KeyVault 的方式是作为一个单一的抽象位置,其中保存所有授予资源访问权限的设置。这使这些事情完全脱离了 CI/CD 管道,并且少了一件需要担心的事情。秘密被缓存,所以我们放在 KeyVault 上的整体负载很低。
    • 如果您使用的是 VSTS,也可以保护变量,因此一旦保存就没有人能够恢复它们 - 这样就不需要使用 KV。
    猜你喜欢
    • 2022-06-10
    • 2019-10-23
    • 1970-01-01
    • 1970-01-01
    • 2018-05-19
    • 1970-01-01
    • 2021-02-06
    • 1970-01-01
    • 2020-10-22
    相关资源
    最近更新 更多