Azure functions 来自KeyVault的Azure函数BlobTrigger连接

Azure functions 来自KeyVault的Azure函数BlobTrigger连接,azure-functions,azure-keyvault,Azure Functions,Azure Keyvault,摘要:我可以使用KeyVault向Blob存储绑定提供连接字符串功能吗 我最近将我所有的连接字符串和机密从Azure Function应用程序设置中移出并移到了KeyVault中。这包括我引用的各种存储帐户的连接字符串。我现在正在处理Azure Blob存储绑定,但似乎()引用连接字符串的所有方法都会解析为应用程序级别的设置 我不想在两个不同的地方有这个秘密。是否有方法指定存储帐户连接字符串ala KeyVault?如果您询问是否可以执行以下操作: [FunctionName("ResizeIm

摘要:我可以使用KeyVault向Blob存储绑定提供连接字符串功能吗

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


我不想在两个不同的地方有这个秘密。是否有方法指定存储帐户连接字符串ala KeyVault?

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

[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管道中

我可能有不同的看法,但我相信我同意@ThatCreole的观点,这是一种痛苦。集中化配置和从部署的代码中删除机密不仅关系到在CI/CD管道中替换它的位置。如果文件系统遭到破坏,访问配置文件会进一步破坏您的基础结构。通过Azure,我们能够使用托管服务标识,在系统运行和Azure active directory的基础硬件上创建信任。这样就不需要在任何一点将任何机密存储在配置中,包括访问密钥库的机密。Azure函数可以利用这一点,但这只在应用程序的启动/运行时有用。触发仍然依赖于功能启动,甚至到达该点,这会导致一点表面曝光


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

我创建了一个nuget包,它将Azure KeyVault集成到Azure函数中,并支持连接字符串等。这实际上在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;
}
静态IWebJobsBuilder AddAzureKeyVault(此IWebJobsBuilder,
Func(配置)
{
var configurationBuilder=new configurationBuilder();
var descriptor=builder.Services.FirstOrDefault(d=>d.ServiceType==typeof(IConfiguration));
if(描述符?.ImplementationInstance为IConfigurationRoot配置)
{
configurationBuilder.AddConfiguration(配置);
}
configurationBuilder.AddAzureKeyVault(..);
var config=configurationBuilder.Build();
Replace(servicescriptor.Singleton(typeof(IConfiguration),config));
返回生成器;
}

您可以在找到这方面的来源。

请参阅此答案,它可能对您的情况很有用:谢谢。我的理由是后者。我现在使用KeyVault的方式是将其作为一个单独的抽象场所,在这里保存所有允许访问资源的设置。这将使这些内容完全脱离CI/CD管道,因此不必担心。机密被缓存,因此我们在KeyVault上的总负载很低。如果您使用VST,也可以保护变量,因此保存后没有人能够还原它们-这样就不需要使用KV。看起来像是从.net core 3.1开始的(也可能是.net core 3.0)这将不再有效,因为
描述符?.ImplementationInstance
将为空。在dotnet/extensions中打开的问题