如何在C#中从Azure App Config获取KeyVault URI而非密钥值?
获取Azure App Config中的KeyVault原始引用URI(而非解析后的密钥值)
问题原因
你当前通过ConfigureKeyVault配置后,Azure App Config扩展会自动解析KeyVault引用,将配置值替换为实际的密钥内容,因此通过IConfiguration拿到的是解密后的密钥,而非原始引用URI。
解决方案
方法1:使用Azure App Configuration客户端库直接查询(推荐用于迁移场景)
直接通过Azure.Data.AppConfiguration SDK与Azure App Config服务交互,获取原始配置值(包括KeyVault引用URI),无需自动解析。
- 安装NuGet包:
Install-Package Azure.Data.AppConfiguration
- 示例代码:
using Azure.Data.AppConfiguration; // 初始化App Config客户端 var configClient = new ConfigurationClient(connectionStringToAppConfig); // 获取所有配置项(可通过SettingSelector过滤特定键/标签) var allSettings = configClient.GetConfigurationSettings(SettingSelector.All); foreach (var setting in allSettings) { Console.WriteLine($"键: {setting.Key}, 值: {setting.Value}"); // 判断是否为KeyVault引用(格式以@Microsoft.KeyVault(开头) if (setting.Value?.StartsWith("@Microsoft.KeyVault(") == true) { Console.WriteLine("→ 这是KeyVault引用"); // 提取KeyVault信息(支持两种引用格式) if (setting.Value.Contains("SecretUri=")) { // 解析SecretUri格式 var uriStart = setting.Value.IndexOf("SecretUri=") + "SecretUri=".Length; var uriEnd = setting.Value.IndexOf(")", uriStart); var secretUri = setting.Value.Substring(uriStart, uriEnd - uriStart); Console.WriteLine($" Secret URI: {secretUri}"); } else if (setting.Value.Contains("VaultName=") && setting.Value.Contains("SecretName=")) { // 解析VaultName+SecretName格式 var vaultNameStart = setting.Value.IndexOf("VaultName=") + "VaultName=".Length; var vaultNameEnd = setting.Value.IndexOf(",", vaultNameStart); var vaultName = setting.Value.Substring(vaultNameStart, vaultNameEnd - vaultNameStart); var secretNameStart = setting.Value.IndexOf("SecretName=") + "SecretName=".Length; var secretNameEnd = setting.Value.IndexOf(")", secretNameStart); var secretName = setting.Value.Substring(secretNameStart, secretNameEnd - secretNameStart); Console.WriteLine($" 密钥库名称: {vaultName}, 密钥名称: {secretName}"); } } }
方法2:禁用IConfiguration的KeyVault自动解析
如果需要继续使用IConfiguration,可以不配置ConfigureKeyVault,这样获取到的就是原始引用URI,而非解析后的密钥值。
示例代码:
IConfiguration config = new ConfigurationBuilder() .AddAzureAppConfiguration(options => { options.Connect(connectionStringToAppConfig); // 移除ConfigureKeyVault配置,避免自动解析引用 // options.ConfigureKeyVault(kv => kv.SetCredential(new DefaultAzureCredentials())); }) .Build(); // 递归遍历配置节 void TraverseConfig(IConfigurationSection section) { foreach (var childSection in section.GetChildren()) { // 叶子节点(不含子节)即为具体配置项 if (!childSection.GetChildren().Any()) { Console.WriteLine($"键: {childSection.Key}, 值: {childSection.Value}"); if (childSection.Value?.StartsWith("@Microsoft.KeyVault(") == true) { Console.WriteLine("→ 这是KeyVault引用"); } } else { TraverseConfig(childSection); } } } // 启动遍历 TraverseConfig(config.GetChildren());
注意事项
- 方法1更适合迁移场景,能获取配置项的完整元数据(如标签、内容类型、最后修改时间等),便于跨租户迁移时完整复制配置。
- 若需同时获取原始引用和解析后的密钥值,可构建两个
IConfiguration实例:一个启用ConfigureKeyVault用于业务逻辑,另一个不启用用于迁移操作。
内容的提问来源于stack exchange,提问作者Martin Hatch
相关产品推荐
相关产品推荐

