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

.NET Core 6极简托管模型:如何在ConfigureServices中获取Azure KeyVault密钥

解决.NET Core 6 Worker应用中ConfigureServices访问Azure KeyVault密钥的问题

核心问题分析

你当前的代码存在两个关键问题:

  1. 配置构建顺序错误:ConfigureServices先于ConfigureAppConfiguration执行,导致注册服务时KeyVault配置尚未加载
  2. ConfigureServices内手动构建了不包含KeyVault的独立配置实例,无法读取密钥保管库中的内容

方案一:调整配置顺序,使用整合KeyVault的全局配置

将ConfigureAppConfiguration移至ConfigureServices之前,确保注册服务时应用配置已包含KeyVault的内容,同时直接使用Host提供的全局配置,而非手动构建新配置。

修改后的完整代码:

IHost host = Host.CreateDefaultBuilder(args)
    // 先配置应用配置,包含Azure KeyVault
    .ConfigureAppConfiguration((context, config) =>
    {
        if (context.HostingEnvironment.IsDevelopment() || context.HostingEnvironment.IsProduction())
        {
            var root = config.Build();
            using var x509Store = new X509Store(StoreLocation.CurrentUser);
            x509Store.Open(OpenFlags.ReadOnly);

            var x509Certificate = x509Store.Certificates
                .Find(
                    X509FindType.FindByThumbprint,
                    root["AzureADCertThumbprint"],
                    validOnly: false)
                .OfType<X509Certificate2>()
                .Single();

            config.AddAzureKeyVault(
                new Uri($"https://{root["KeyVaultName"]}.vault.azure.net/"),
                new ClientCertificateCredential(
                    root["AzureADDirectoryId"],
                    root["AzureADApplicationId"],
                    x509Certificate));
        }
    })
    // 注册服务时直接使用已包含KeyVault的全局配置
    .ConfigureServices((context, services) =>
    {
        var configuration = context.Configuration;

        // 配置Application Insights
        var aiOptions = new ApplicationInsightsServiceOptions();
        aiOptions.ConnectionString = configuration["APPINSIGHTS_CONNECTIONSTRING"];
        aiOptions.EnableQuickPulseMetricStream = configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableQuickPulseMetricStream");
        aiOptions.EnableEventCounterCollectionModule = configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableEventCounterCollectionModule");
        aiOptions.EnableAppServicesHeartbeatTelemetryModule = configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableAppServicesHeartbeatTelemetryModule");
        aiOptions.EnableAzureInstanceMetadataTelemetryModule = configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableAzureInstanceMetadataTelemetryModule");
        aiOptions.EnableDependencyTrackingTelemetryModule = configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableDependencyTrackingTelemetryModule");
        aiOptions.EnableAdaptiveSampling = configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableAdaptiveSampling");
        aiOptions.EnableHeartbeat = configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableHeartbeat");
        aiOptions.AddAutoCollectedMetricExtractor = configuration.GetSection("ApplicationInsights").GetValue<bool>("AddAutoCollectedMetricExtractor");

        services.AddApplicationInsightsTelemetryWorkerService(aiOptions);

        // ------------------------
        // ----- Lite DB START-----
        // ------------------------
        // 直接从全局配置读取KeyVault中的连接字符串
        var connectionString = configuration.GetSection("LiteDB").GetValue<string>("ConnectionString");
        services.AddSingleton<ILiteDatabase, LiteDatabase>(x => new LiteDatabase(connectionString));
        // -----------------------
        // ----- Lite DB END-----
        // -----------------------

        services.AddTransient<ILogExtension, LogExtension>();
        services.AddHostedService<AzureSignalRService>();
    })
    .Build();

方案二:延迟解析配置(适用于无法调整顺序的场景)

如果因特殊原因无法调整配置构建顺序,可通过IServiceProvider延迟获取已加载KeyVault的配置:

在ConfigureServices中替换LiteDB的注册代码:

// 延迟从服务容器中获取完整配置
services.AddSingleton<ILiteDatabase, LiteDatabase>(sp => 
{
    var configuration = sp.GetRequiredService<IConfiguration>();
    var connectionString = configuration.GetSection("LiteDB").GetValue<string>("ConnectionString");
    return new LiteDatabase(connectionString);
});

额外注意事项

  • 确保KeyVault中已创建对应路径的密钥:例如LiteDB:ConnectionString(配置层级用冒号分隔)
  • 验证用于认证的Azure AD应用拥有KeyVault的Secret Get权限

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 21:36:29