代码之家  ›  专栏  ›  技术社区  ›  H. Pauwelyn

使用密钥库存储ABP框架的默认连接字符串

  •  0
  • H. Pauwelyn  · 技术社区  · 2 年前

    我们已将我的ABP Framework网站上载到Azure Web应用程序,但默认连接字符串存储在Web应用程序的配置中。现在,我们希望将其替换为Azure密钥库,并仅在配置中存储URL。

    如果使用此代码:

    using Azure.Extensions.AspNetCore.Configuration.Secrets;
    using Azure.Identity;
    using Azure.Security.KeyVault.Secrets;
    using Microsoft.Azure.Services.AppAuthentication;
    using Microsoft.Extensions.Configuration;
    using System;
    
    namespace OurNamespace.Utils
    {
        public static class AppAzureKeyVaultConfigurer
        {
            public static IConfigurationBuilder ConfigureAzureKeyVault(this IConfigurationBuilder builder, string azureKeyVaultUrl)
            {
                SecretClient keyVaultClient = new SecretClient(
                    new Uri(azureKeyVaultUrl),
                    new DefaultAzureCredential()
                );
    
                AzureKeyVaultConfigurationOptions options = new AzureKeyVaultConfigurationOptions()
                {
                    ReloadInterval = TimeSpan.FromHours(1)
                };
    
                return builder.AddAzureKeyVault(keyVaultClient, options);
            }
        }
    }
    

    里面 Program 班级 OurNamespace.HttpApi.Host 项目,下一个代码将被调用:

    internal static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .AddAppSettingsSecretsJson()
            .ConfigureAppConfiguration(build =>
            {
                IConfigurationBuilder configuration = build
                    .AddJsonFile("appsettings.secrets.json", optional: true)
                    .ConfigureAzureKeyVault("☺ --> the url to the key vault");
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            })
            .UseAutofac()
            .UseSerilog();
    

    将评估令牌放入 OurApplicationDbContext :

    [ReplaceDbContext(typeof(IIdentityProDbContext), typeof(ISaasDbContext), typeof(ILanguageManagementDbContext), typeof(IAuditLoggingDbContext), typeof(ITextTemplateManagementDbContext), typeof(IIdentityServerDbContext), typeof(IPaymentDbContext), typeof(IPermissionManagementDbContext), typeof(ISettingManagementDbContext), typeof(IFeatureManagementDbContext), typeof(IBackgroundJobsDbContext), typeof(IBlobStoringDbContext))]
    [ConnectionStringName("Default")]
    public class OurApplicationDbContext : AbpDbContext<OurApplicationDbContext>, IOurApplicationDbContext, IIdentityProDbContext, ISaasDbContext, ILanguageManagementDbContext, IAuditLoggingDbContext, ITextTemplateManagementDbContext, IIdentityServerDbContext, IPaymentDbContext, IPermissionManagementDbContext, ISettingManagementDbContext, IFeatureManagementDbContext, IBackgroundJobsDbContext, IBlobStoringDbContext
    {
        private readonly IConfiguration _configuration;
    
        // All implementations of all interfaces here
    
        public OurApplicationDbContext(DbContextOptions<OurApplicationDbContext> options, IConfiguration configuration)
            : base(options)
        {
            _configuration = configuration;
        }
    
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured) // <-- also a break point here will not be hit.
                optionsBuilder.UseSqlServer(_configuration.GetConnectionString("Default"));
        }
    }
    

    里面 appsettings.json 这个 Connectionstring:Default 已删除,因为它必须从密钥库中取出。

    也在 DbContext 关于 OurNamespace.EntityFrameworkCore 项目,所有这些 DbContext 替换的是:

    • IIdentityProDbContext
    • ISaasDbContext
    • ILanguageManagementDbContext
    • IAuditLoggingDbContext
    • ITextTemplateManagementDbContext
    • IIdentityServerDbContext
    • IPaymentDbContext
    • IPermissionManagementDbContext
    • ISettingManagementDbContext
    • IFeatureManagementDbContext
    • IBackgroundJobsDbContext
    • IBlobStoringDbContext

    它将给出下一个错误:

    ArgumentNullException : 值不能为空。(参数 connectionString )

    DependencyResolutionException : 激活时引发异常: Volo.Abp.LanguageManagement.EntityFrameworkCore.ILanguageManagementDbContext → OurNamespace.EntityFrameworkCore.OurApplicationDbContext → Microsoft.EntityFrameworkCore.DbContextOptions<OurNamespace.EntityFrameworkCore.OurApplicationDbContext> .

    使现代化

    如果我什么都不做 (将我的连接字符串密钥放入 应用设置。json (文件) 这个 ILanguageManagementDbContext 将按预期工作。此外,还将从钥匙库中取出其他钥匙。还检查了钥匙库中是否存储了正确的钥匙,没有发现任何问题。

    规格

    • ABP框架版本: 5.0.0
    • 用户界面类型 :棱角分明
    • 数据库提供者 :EF核心
    0 回复  |  直到 2 年前
        1
  •  1
  •   Tiny Wang    2 年前

    跟随 this documen t、 它显示了当我们想要将azure keyvault机密添加到配置中时,我们可以使用 managed identities 获取azure资源。这就是OP所用的 DefaultAzureCredential .使用 DefaultAzureCredential 必须 do some configuration 确保我们已经为我们的申请提供了凭证。对于本地测试,我们使用了visual studio,因此我们可以使用 azure key vault access permission 要登录visual studio,这可以是凭据之一。如果我们已经将应用程序发布到azure应用程序服务,那么还要将web应用程序服务原则添加到密钥库访问策略中。

    enter image description here

    这是我的示例代码。

    我的节目。cs,加上 ConfigureAppConfiguration :

    using Azure.Extensions.AspNetCore.Configuration.Secrets;
    using Azure.Identity;
    using Azure.Security.KeyVault.Secrets;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.Hosting;
    using System;
    
    namespace WebMvcAppLinkDb
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                CreateHostBuilder(args).Build().Run();
            }
    
            public static IHostBuilder CreateHostBuilder(string[] args) =>
                Host.CreateDefaultBuilder(args)
                    .ConfigureAppConfiguration((context, config) =>
                    {
                        var builtConfig = config.Build();
                        var secretClient = new SecretClient(
                            new Uri($"https://{builtConfig["KeyVaultName"]}.vault.azure.net/"),
                            new DefaultAzureCredential());
                        config.AddAzureKeyVault(secretClient, new KeyVaultSecretManager());
                    })
                    .ConfigureWebHostDefaults(webBuilder =>
                    {
                        webBuilder.UseStartup<Startup>();
                    });
        }
    }
    

    我的创业公司。反恐精英,

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();
        //use connection string stored in appsetting
        //services.AddDbContext<MyDbContext>(options =>options.UseSqlServer(Configuration.GetConnectionString("MvcMovieContext")));
        //use connection string stored in azure key vault
        //after adding Azure Key Vault configuration provider, we debug code here, and will see Cigfiguration has one more provider from keyvault
        var a = Configuration.GetSection("LocalDbConnectionString");
        var b = a.Value;
        var c = b.ToString();
        //I stored connection string with name "LocalDbConnectionString" in azure keyvault, but when I get the value from key vault
        //I don't know why the data format like Server=(localdb)\\\\xxdb, so I need to remove \\
        var d = c.Remove(16,1);
        services.AddDbContext<MyDbContext>(options =>options.UseSqlServer(d));
    }
    

    我的应用程序设置:

    {
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft": "Warning",
          "Microsoft.Hosting.Lifetime": "Information"
        }
      },
      "AllowedHosts": "*",
      //"ConnectionStrings": {
      //  "MvcMovieContext": "Server=(localdb)\\xxdb;Database=xx;Trusted_Connection=True;MultipleActiveResultSets=true"
      //},
      "KeyVaultName": "my_keyvault_name"
    }
    
    推荐文章