You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在.NET 7 Web API中手动解析Azure Key Vault密钥适配IOptions<T>

解决方案

1. 添加配置绑定逻辑

在Program.cs中补充配置绑定步骤,将配置节与Options类关联并注入依赖注入容器:

var builder = WebApplication.CreateBuilder(args);
{
    var env = builder.Environment;

    // 加载基础配置
    builder.Configuration.AddAppConfiguration(env);
    // 加载Key Vault配置
    builder.Configuration.AddAzureKeyVaultConfiguration(env);

    // 绑定配置到Options类,注入DI容器
    builder.Services.Configure<ServiceBusConfigOption>(
        builder.Configuration.GetSection(ServiceBusConfigOption.SectionName));

    builder.Services.Configure<StorageConfigOption>(
        builder.Configuration.GetSection(StorageConfigOption.SectionName));

    // 注册其他业务服务...
}

var app = builder.Build();

// 配置中间件...

app.Run();

2. 调整appsettings.json占位符

@Microsoft.KeyVault(...)是Azure App Service专属格式,非App Service环境无法自动解析。直接将ConnectionString设为空或默认值,Key Vault加载后会自动覆盖对应配置:

"ServiceBusConfigOption": {
    "ConnectionString": "",
    "TopicsEmailTemplate": "EmailTemplates",
    "TopicUserSetting": "UserSettings"
},

"StorageConfigOption": {
    "ConnectionString": ""
}

3. 优化Key Vault加载逻辑

修改AddAzureKeyVaultConfiguration方法,使用配置中已有的Key Vault URL,添加映射规则确保密钥名称与配置层级匹配,并优化证书获取逻辑:

public static IConfigurationBuilder AddAzureKeyVaultConfiguration(this IConfigurationBuilder configurationBuilder, IWebHostEnvironment hostingEnvironment)
{
    if (!hostingEnvironment.IsEnvironment("Development"))
    {
        var builtConfig = configurationBuilder.Build();
        // 直接读取配置中的Key Vault URL,避免拼接错误
        var keyVaultEndpoint = builtConfig["KeyVaultConfigOption:Url"];
        var clientId = builtConfig["KeyVaultConfigOption:ClientId"];
        var thumbprint = builtConfig["KeyVaultConfigOption:Thumbprint"];
        var tenantId = builtConfig["KeyVaultConfigOption:TenantId"];

        // 校验配置完整性
        if (string.IsNullOrEmpty(keyVaultEndpoint) || string.IsNullOrEmpty(clientId) || string.IsNullOrEmpty(thumbprint) || string.IsNullOrEmpty(tenantId))
        {
            throw new InvalidOperationException("Key Vault配置参数不完整");
        }

        var certificate = GetCertificate(thumbprint);
        var clientCertificateCredential = new ClientCertificateCredential(tenantId, clientId, certificate);

        // 配置Key Vault加载选项,双横线映射配置层级的冒号
        configurationBuilder.AddAzureKeyVault(
            new Uri(keyVaultEndpoint),
            clientCertificateCredential,
            new AzureKeyVaultConfigurationOptions
            {
                SecretNameSeparator = "--",
                ReloadInterval = TimeSpan.FromMinutes(5) // 可选:自动刷新配置
            });
    }
    
    return configurationBuilder;
}

private static X509Certificate2 GetCertificate(string thumbprint)
{
    // 使用using确保证书商店自动关闭
    using var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
    store.Open(OpenFlags.ReadOnly);

    var cert = store.Certificates
        .OfType<X509Certificate2>()
        .FirstOrDefault(x => x.Thumbprint.Equals(thumbprint, StringComparison.OrdinalIgnoreCase));

    if (cert == null)
        throw new InvalidOperationException($"未找到指纹为{thumbprint}的证书");

    return cert;
}

4. 配置Azure Key Vault密钥

在Azure Key Vault中创建对应密钥,名称需用双横线代替配置层级的冒号:

  • ServiceBus连接字符串:ServiceBusConfigOption--ConnectionString
  • 存储账户连接字符串:StorageConfigOption--ConnectionString

5. 在服务中使用配置

在业务服务中注入IOptions<ServiceBusConfigOption>即可获取填充后的配置值:

public class ServiceBusService
{
    private readonly ServiceBusConfigOption _config;

    public ServiceBusService(IOptions<ServiceBusConfigOption> config)
    {
        _config = config.Value;
        // 使用_config.ConnectionString初始化服务
    }
}

记得在Program.cs中注册该服务:

builder.Services.AddScoped<ServiceBusService>();

内容的提问来源于stack exchange,提问作者Rakesh Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 12:32:11