使用 Azure.Security.KeyVault.Secrets 的网络核心密钥保管库配置
Posted
技术标签:
【中文标题】使用 Azure.Security.KeyVault.Secrets 的网络核心密钥保管库配置【英文标题】:Net core Key vault configuration using Azure.Security.KeyVault.Secrets 【发布时间】:2020-10-11 15:23:40 【问题描述】:我发现使用托管标识很容易连接到 Azure KeyVault。文档显示了如何做到这一点:
var azureServiceTokenProvider = new AzureServiceTokenProvider();
var keyVaultClient = new KeyVaultClient(
new KeyVaultClient.AuthenticationCallback(
azureServiceTokenProvider.KeyVaultTokenCallback));
config.AddAzureKeyVault(
$"https://builtConfig["KeyVaultName"].vault.azure.net/",
keyVaultClient,
new DefaultKeyVaultSecretManager());
然后我意识到它需要包 Microsoft.Azure.KeyVault
已弃用。所以我很难弄清楚如何使用 SDK 4 完成上述操作。我找到的所有文档都与 SDK 3 相关。
[编辑]
我发现以下代码可以使用带有 SDK 4 的托管身份获取 azure KeyVault Secret。但是我看不到如何将其添加到我的配置中。它曾经使用 Microsoft.Extensions.Configuration.AzureKeyVault 包中的 config.AddAzureKeyVault()
完成,但它与 SDK 4 SecretClient 不兼容:
return Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((context, config) =>
var azureCredentialOptions = new DefaultAzureCredentialOptions();
var credential = new DefaultAzureCredential(azureCredentialOptions);
var secretClient = new SecretClient(new System.Uri("https://mykeyvault.vault.azure.net/"), credential);
var secret = secretClient.GetSecret("StorageConnectionString");
config.AddAzureKeyVault()
)
.ConfigureWebHostDefaults(webBuilder =>
webBuilder.UseStartup<Startup>();
);
【问题讨论】:
docs.microsoft.com/en-us/azure/key-vault/secrets/… 这是 v4 文档。 您是如何发现它已被弃用的?查看nuget,版本似乎还可以,不是最新但未弃用:nuget.org/packages/Microsoft.Azure.KeyVault @Thomas 看上面的截图 我猜你可以改正你自己的配置生成器? microsoft.azure.keyvault 包已弃用 【参考方案1】:具有版本 4 库的最新工作解决方案。我的堆栈是 .netcore 3.1,我在 Azure Web 应用程序中使用它来访问来自 Azure KeyVault 的机密。
第一件事 - 浏览这个MS Doc link
using Azure.Identity;
using Azure.Security.KeyVault.Secrets;
//..........
var kvUri = "https://YOURVAULTNAME.vault.azure.net/";
var client = new SecretClient(new Uri(kvUri), new DefaultAzureCredential());
KeyVaultSecret secret = client.GetSecret("SECRETNAME");
// Can also use await.....GetSecretAsync()
this.ConnectionString = secret.Value.ToString();
\\thats my internal variable, secret.Value.ToString() is required value
我在这里假设你有
-
在 Azure 中创建了 keyVault
在应用服务中创建了托管标识(使用应用服务中的“身份”选项)
在 Azure KeyVault 中添加了上述标识(“访问策略”选项)
【讨论】:
【参考方案2】:供您参考,如果您在应用服务或 Azure Functions 应用程序设置中使用 Azure Key Vault 机密,则无需添加额外代码即可获取密钥保管库值。
您只需使用您的密钥保管库引用更改您的应用设置值(在 Azure 门户中)。
具体步骤看https://docs.microsoft.com/en-us/azure/app-service/app-service-key-vault-references
使用密钥保管库引用设置示例: "name": "DatabaseSettings:ConnectionString", "值": "@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/DatabaseConnectionSettingSecret/ec96f02080254fxxxxxxxxxxxxxxx)", “插槽设置”:假
但这不适用于本地开发,您应该使用普通的秘密值。但对我来说没关系,因为您的本地开发使用不同的秘密值,并且您没有将 local.settings.json 添加到源代码管理中。
【讨论】:
【参考方案3】:事实证明,我找到了使用 SDK 4 的正确方法。我必须安装包 azure.extensions.aspnetcore.configuration.secrets
,然后代码很简单:
var credential = new DefaultAzureCredential();
config.AddAzureKeyVault(new System.Uri("https://mykv.vault.azure.net/"), credential);
然后使用它
configuration["StorageConnectionString"]
【讨论】:
成功了!我尝试了很多组合,但这条线有效。我没有在任何 ms 文档中找到它。谢了!【参考方案4】:第一件事是Microsoft.Azure.KeyVault
没有被弃用而是被替换。使用旧的 nuget 包仍然是一个有效的选择。
我想在未来,Microsoft.Extensions.Configuration.AzureKeyVault
nuget 包将使用新的Azure.Security.KeyVault.Secrets
包。
根据我的经验,我会坚持使用现有的库并等待未来的更新。
如果你真的想使用Azure.Security.KeyVault.Secrets
,你可以实现自己的custom configuration builder。
我查看了github 上现有的密钥保管库配置代码,这里有一个您可以使用的简化/修改版本。
首先安装这些nuget包Azure.Identity
和Azure.Security.KeyVault.Secrets
。
新的密钥保管库机密包使用 IAsyncEnumerable
,因此您需要将项目更新为面向 C#8.0:使用 <LangVersion>8.0</LangVersion>
更新您的 csproj 文件。
Azure Key Vault Secret 配置代码:
public interface IKeyVaultSecretManager
bool ShouldLoad(SecretProperties secret);
string GetKey(KeyVaultSecret secret);
public class DefaultKeyVaultSecretManager : IKeyVaultSecretManager
public bool ShouldLoad(SecretProperties secret) => true;
public string GetKey(KeyVaultSecret secret)
=> secret.Name.Replace("--", ConfigurationPath.KeyDelimiter);
public class AzureKeyVaultConfigurationProvider : ConfigurationProvider
private readonly SecretClient _client;
private readonly IKeyVaultSecretManager _manager;
public AzureKeyVaultConfigurationProvider(SecretClient client, IKeyVaultSecretManager manager)
_client = client ?? throw new ArgumentNullException(nameof(client));
_manager = manager ?? throw new ArgumentNullException(nameof(manager));
public override void Load() => LoadAsync().ConfigureAwait(false).GetAwaiter().GetResult();
private async Task LoadAsync()
var data = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
await foreach (var secretProperties in _client.GetPropertiesOfSecretsAsync())
if (!_manager.ShouldLoad(secretProperties) || secretProperties?.Enabled != true)
continue;
var secret = await _client.GetSecretAsync(secretProperties.Name).ConfigureAwait(false);
var key = _manager.GetKey(secret.Value);
Data.Add(key, secret.Value.Value);
Data = data;
public class AzureKeyVaultConfigurationSource : IConfigurationSource
public SecretClient Client get; set;
public IKeyVaultSecretManager Manager get; set;
public IConfigurationProvider Build(IConfigurationBuilder builder)
return new AzureKeyVaultConfigurationProvider(Client, Manager);
public static class AzureKeyVaultConfigurationExtensions
public static IConfigurationBuilder AddAzureKeyVault(
this IConfigurationBuilder configurationBuilder,
SecretClient client,
IKeyVaultSecretManager manager = null)
if (configurationBuilder == null)
throw new ArgumentNullException(nameof(configurationBuilder));
if (client == null)
throw new ArgumentNullException(nameof(client));
configurationBuilder.Add(new AzureKeyVaultConfigurationSource()
Client = client,
Manager = manager ?? new DefaultKeyVaultSecretManager()
);
return configurationBuilder;
您现在可以像这样在项目中使用此配置生成器:
public class Program
public static void Main(string[] args)
CreateWebHostBuilder(args).Build().Run();
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((context, config) =>
var azureCredentialOptions = new DefaultAzureCredentialOptions();
var credential = new DefaultAzureCredential(azureCredentialOptions);
var secretClient = new SecretClient(new System.Uri("https://mykeyvault.vault.azure.net/"), credential);
config.AddAzureKeyVault(secretClient);
)
.UseStartup<Startup>();
【讨论】:
我希望微软在创建新库时停止半途而废:/ @Thomas AddAzureKeyVault 有两个参数。 我相信有一个小错字。我将Data.Add(key, secret.Value.Value);
更改为 => data.Add(key, secret.Value.Value);
之后我可以在其他地方访问 IConfiguration 的 configuration["someKey"]
。【参考方案5】:
我正在使用这样的东西,
var keyVaultEndpoint = GetKeyVaultEndpoint();
if (!string.IsNullOrEmpty(keyVaultEndpoint))
// Pass appropriate connection string
var azureServiceTokenProvider = new
AzureServiceTokenProvider(certThumbprintConnectionString);
var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(
azureServiceTokenProvider.KeyVaultTokenCallback));
config.AddAzureKeyVault(keyVaultEndpoint, keyVaultClient, new DefaultKeyVaultSecretManager());
private static string GetKeyVaultEndpoint() => "https://<<key-vault-name>>.vault.azure.net";
【讨论】:
查看我的编辑。我想用托管身份来做这件事,现在可以工作了,但是我不知道如何将它添加到配置中以上是关于使用 Azure.Security.KeyVault.Secrets 的网络核心密钥保管库配置的主要内容,如果未能解决你的问题,请参考以下文章
在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?
Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)