首页 > 解决方案 > 通过 KeyVault 从 Azure 功能连接到 SQL Server

问题描述

我尝试使用密钥库机密从本地 azure 函数连接到 sql server。我设置了一个函数启动类来配置连接:

[assembly: FunctionsStartup(typeof(MyNamespace.Startup))]
//namespace
public class Startup : FunctionsStartup
{
    public Startup()
    {
    }

    public override void Configure(IFunctionsHostBuilder builder)
    {
        string basePath = IsDevelopmentEnvironment() ?
            Environment.GetEnvironmentVariable("AzureWebJobsScriptRoot") :
            $"{Environment.GetEnvironmentVariable("HOME")}\\site\\wwwroot";

        var configurationBuilder = new ConfigurationBuilder()
            .SetBasePath(basePath)
            .AddJsonFile("local.settings.json", optional: true, reloadOnChange: false)  // secrets go here. This file is excluded from source control.
            .AddEnvironmentVariables();

        var builtConfig = configurationBuilder.Build();

        var azureServiceTokenProvider = new AzureServiceTokenProvider();
        var keyVaultClient = new KeyVaultClient(
            new KeyVaultClient.AuthenticationCallback(
                azureServiceTokenProvider.KeyVaultTokenCallback));

        configurationBuilder.AddAzureKeyVault($"https://{builtConfig.GetSection("KeyVaultSettings")["KeyVaultName"]}.vault.azure.net/",
            keyVaultClient,
            new DefaultKeyVaultSecretManager());

        var builtConfigWithKeyVault = configurationBuilder.Build(); //necessary?

        // Registering services
        builder
            .Services
                .AddScoped<IUnitOfWork, UnitOfWork>()
                .AddDbContext<DomainDbContext>(
                    options => options.UseSqlServer(builtConfigWithKeyVault.GetSection("KeyVaultSettings")["DatabaseConnectionStringSecretName"]));
    }

    public bool IsDevelopmentEnvironment()
    {
        return "Development".Equals(Environment.GetEnvironmentVariable("AZURE_FUNCTIONS_ENVIRONMENT"), StringComparison.OrdinalIgnoreCase);
    }
}

local.settings.json中,我定义了密钥保管库设置:

"KeyVaultSettings": {
    "KeyVaultName": "KeyVault",
    "DatabaseConnectionStringSecretName": "ConnectionString"
}

我的问题是没有建立连接,因为在DBContextOptions中,连接字符串是“ConnectionString”

public DomainDbContext(IServiceProvider serviceProvider, DbContextOptions<DomainDbContext> options) : base(options)
{
    //options has wrong connection string
}

代码有问题还是通常无法从本地 Azure 功能访问密钥保管库?!

标签: sql-serverazure-functionsazure-keyvault

解决方案


如果要从 Azure Key Vault 中获取连接字符串,请参考以下代码

[assembly: FunctionsStartup(typeof(FunctionApp1.Startup))]
namespace FunctionApp1
{
    class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            string basePath = IsDevelopmentEnvironment() ?
            Environment.GetEnvironmentVariable("AzureWebJobsScriptRoot") :
            $"{Environment.GetEnvironmentVariable("HOME")}\\site\\wwwroot";

            var configurationBuilder = new ConfigurationBuilder()
                .SetBasePath(basePath)
                .AddJsonFile("local.settings.json", optional: true, reloadOnChange: false)
                .AddEnvironmentVariables();
            var currentConfiguration = configurationBuilder.Build();
            var azureServiceTokenProvider = new AzureServiceTokenProvider();
            var kvClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
            configurationBuilder
                        .AddAzureKeyVault($"https://{currentConfiguration["KeyVaultSettings:KeyVaultName"]}.vault.azure.net/",
                          kvClient, new DefaultKeyVaultSecretManager());
            var keyConfig = configurationBuilder.Build();
           
            var conStr= keyConfig.GetValue<string>(currentConfiguration["KeyVaultSettings:DatabaseConnectionStringSecretName"]);

            builder.Services
                    .AddDbContext<DomainDbContext>(options => options.UseSqlServer(conStr));
           


        }


        public bool IsDevelopmentEnvironment()
        {
            return "Development".Equals(Environment.GetEnvironmentVariable("AZURE_FUNCTIONS_ENVIRONMENT"), StringComparison.OrdinalIgnoreCase);
        }
    }
}

在此处输入图像描述

此外,在您将函数部署到 Azure 后,我们可以使用 Azure 密钥库参考来简化您的代码。有关更多详细信息,请参阅此处此处

例如

  1. 在 Azure 函数中启用 Azure MSI

  2. 在 Key Vault 中为你之前创建的应用程序标识创建访问策略

  3. 在 Azure Function Application Settings 中添加引用

@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931)
  1. 阅读代码中的应用程序设置

推荐阅读