通过 KeyVault 从 Azure 功能连接到 SQL 服务器
Connect to SQL Server from Azure function by KeyVault
我尝试使用密钥保管库机密从本地 azure 函数连接到 sql 服务器。
我设置了一个函数启动 class 来配置连接:
[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 功能访问密钥保管库?!
如果想从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);
}
}
}
此外,在您将Function部署到Azure之后,我们可以使用Azure key vault reference来简化您的代码。详情请参考here and here
例如
在 Azure 函数中启用 Azure MSI
在 Key Vault 中为您之前创建的应用程序身份创建访问策略
在 Azure 函数应用程序设置中添加引用
@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931)
- 阅读代码中的应用程序设置
我尝试使用密钥保管库机密从本地 azure 函数连接到 sql 服务器。 我设置了一个函数启动 class 来配置连接:
[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 功能访问密钥保管库?!
如果想从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);
}
}
}
此外,在您将Function部署到Azure之后,我们可以使用Azure key vault reference来简化您的代码。详情请参考here and here
例如
在 Azure 函数中启用 Azure MSI
在 Key Vault 中为您之前创建的应用程序身份创建访问策略
在 Azure 函数应用程序设置中添加引用
@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931)
- 阅读代码中的应用程序设置