首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Net 6最小托管模型->如何在ConfigureServices中获取Azure ConfigureServices密钥

Net 6最小托管模型->如何在ConfigureServices中获取Azure ConfigureServices密钥
EN

Stack Overflow用户
提问于 2022-07-16 12:39:45
回答 2查看 413关注 0票数 2

我有一个.NET核心6辅助应用程序,我已经配置它使用Azure KayVault (新手到KeyVault)

注册服务时,我需要从保险库获得一个密钥,但我发现到keyVault服务的连接还没有启动,因此出现了典型的鸡和蛋的情况。

在ConfigureServices中注册服务时,如何访问密钥?

下面的代码示例显示了我需要获取使用LiteDB的连接字符串,但是我将有其他需要类似解决方案的用例:

代码语言:javascript
复制
IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
    var configuration = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .Build();

    // See notes in appsettings.josn file.
    // See https://learn.microsoft.com/en-us/azure/azure-monitor/app/worker-service
    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.EnableEventCounterCollectionModule = configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableEventCounterCollectionModule");
    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-----
    // ------------------------

    // *This doesnt work becuase the keyvault client hasnt started up yet!!!*
    var connectionString = configuration.GetSection("LiteDB").GetValue<string>("ConnectionString");

    // HOW DO I GET THE KEY VAUT KEY HERE???
    services.AddSingleton<ILiteDatabase, LiteDatabase>(x => new LiteDatabase(connectionString));

    // -----------------------
    // ----- Lite DB END-----
    // -----------------------

    // Repository used for our own logging events throughout the business logic code base.
    services.AddTransient<ILogExtension, LogExtension>();
    // Add the Background Services
    services.AddHostedService<AzureSignalRService>();
})
.ConfigureAppConfiguration((context, config) => // Azure KeyVault Configuration
{
    if (context.HostingEnvironment.IsDevelopment() | context.HostingEnvironment.IsProduction())
    {
        // See https://learn.microsoft.com/en-us/aspnet/core/security/key-vault-configuration?view=aspnetcore-6.0
        // See https://github.com/dotnet/AspNetCore.Docs/blob/main/aspnetcore/security/key-vault-configuration/samples/3.x/SampleApp/Startup.cs
        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));
    }
})
.Build();
EN

回答 2

Stack Overflow用户

发布于 2022-07-16 13:39:48

方法是创建一个服务集合扩展类,并在Program.cs中指向这个类,而不是在ConfigureServices中注册该服务。

从KeyVault获取属性时需要解析appsettings.json键的任何代码现在都在工作。对我来说,这似乎很幸运,我只能假设服务扩展知道在启动的第一阶段之后返回并得到任何丢失的密钥。

Program.cs

代码语言:javascript
复制
IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
    var configuration = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .Build();

    // ------------------------
    // ----- Lite DB START-----
    // ------------------------

    // ----- BAD -----
    // *This doesnt work becuase the keyvault client hasnt started up yet!!!*
    var connectionString = configuration.GetSection("LiteDB").GetValue<string>("Password");
    // Simply returns the native value in app settings, rather than the actual key value stored in Azure KeyVault
    Console.WriteLine(connectionString); 
    // ---------------------------------

    // ----- Solution -----
    // Add the IService Collection Extension, see seperate class further down...
    services.AddDatabase();

    // -----------------------
    // ----- Lite DB END-----
    // -----------------------

    // Repository used for our own logging events throughout the business logic code base.
    services.AddTransient<ILogExtension, LogExtension>();
    // Add the Background Services
    services.AddHostedService<AzureSignalRService>();
})
.ConfigureAppConfiguration((context, config) => // Azure KeyVault Configuration
{
    if (context.HostingEnvironment.IsDevelopment() | context.HostingEnvironment.IsProduction())
    {
        // See https://learn.microsoft.com/en-us/aspnet/core/security/key-vault-configuration?view=aspnetcore-6.0
        // See https://github.com/dotnet/AspNetCore.Docs/blob/main/aspnetcore/security/key-vault-configuration/samples/3.x/SampleApp/Startup.cs
        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));
    }
})
.Build();

独立的IServiceCollection类:

代码语言:javascript
复制
internal static class ServiceCollectionDatabaseExtensions
{
    public static IServiceCollection AddDatabase(this IServiceCollection services)
    {

        var config = services.BuildServiceProvider().GetService<IConfiguration>();
        var password = config!.GetSection("LiteDB").GetValue<string>("Password");
        Console.WriteLine(password); // This now returns the correct key vaue pulled from Azure Key Vault

        var connectionString = "Filename=C:\'database.db;Connection=shared;Password=" + password;
        Console.WriteLine(connectionString);
        
        services.AddSingleton<ILiteDatabase, LiteDatabase>(x => new LiteDatabase(connectionString));

        // Other services here...

        return services;
    }
}
票数 0
EN

Stack Overflow用户

发布于 2022-07-17 21:31:27

ConfigureAppConfiguration运行在ConfigureServices之前,因此当您配置服务时,配置已经加载。逻辑上应该是这样的:

代码语言:javascript
复制
IHost host = Host.CreateDefaultBuilder(args)    
.ConfigureAppConfiguration((context, config) =>
{
  config.AddAzureKeyVault(...);
})
.ConfigureServices(services =>
{
  ... 
})
.Build();

在您的ConfigureServices方法中,您只需要重新创建包含appsettings.json文件的配置,这样它就永远不会从密钥库配置中获得秘密。还有另一个接受HostbuilderContext的重载

代码语言:javascript
复制
.ConfigureServices((context, services) =>
{
  // Get the configuration
  var configuration = context.Configuration;
  ...
})
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73004288

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档