.NET 6如何仅用单个appsettings.json并从Azure Key Vault取密钥
我正在使用.NET 6,希望实现两个目标:
- 不再维护多个
appsettings.{environmentname}.json文件,仅使用单个appsettings.json适配不同环境; - 移除
appsettings.{environmentname}.json中的硬编码内容以支持目标1(当前我在对应配置文件中硬编码了数据库连接字符串、Key Vault配置等密钥信息,希望改为从已存储这些密钥的Azure Key Vault读取)。
当前代码片段
我目前维护两个appsettings.{environmentname}.json文件(Development和Release)的代码如下:
var builder = WebApplication.CreateBuilder(args); var hostingEnvironment = builder.Environment; if (hostingEnvironment.IsDevelopment()) { builder.Configuration.SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", false, true) .AddJsonFile($"appsettings.Development.json", false, true) .AddEnvironmentVariables(); } else { builder.Configuration.SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", false, true) .AddJsonFile($"appsettings.Release.json", false, true) .AddEnvironmentVariables(); }
调研与疑问
针对目标1,我尝试过如下写法,但不确定在CI/CD自动部署的场景下,能否在流水线中设置ASPNETCORE_ENVIRONMENT的值:
builder.Configuration.SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", false, true) .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable( "ASPNETCORE_ENVIRONMENT")}.json", false, true) .AddEnvironmentVariables();
针对目标2,我尝试移除环境配置文件中的硬编码密钥,并按如下方式配置Key Vault,但未生效:
builder.Services.Configure<KeyVaultConfig>(options => builder.Configuration.GetSection("KeyVaultConfig").Bind(options)); if (!string.IsNullOrEmpty(builder.Configuration["KeyVaultConfig:KeyVaultUrl"])) { var credentials = new ClientSecretCredential(builtConfig["KeyVaultConfig:TenantID"], builtConfig["KeyVaultConfig:ClientID"], builtConfig["KeyVaultConfig:ClientKey"]); var secretClient = new SecretClient(new Uri(builtConfig["KeyVaultConfig:KeyVaultUrl"]), credentials); //builder.Configuration.AddAzureKeyVault... }
目标1:单appsettings.json适配多环境
简化配置加载逻辑
直接去掉所有环境专属的appsettings.{env}.json文件,只保留appsettings.json。.NET 6的WebApplication.CreateBuilder默认已包含基础配置加载逻辑,如需自定义可简化为:
var builder = WebApplication.CreateBuilder(args); // 仅加载主配置文件,结合环境变量实现多环境适配 builder.Configuration .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddEnvironmentVariables();
CI/CD中设置ASPNETCORE_ENVIRONMENT
完全可以在流水线中设置该环境变量,主流工具的配置方式:
- Azure DevOps:在流水线「变量」面板添加
ASPNETCORE_ENVIRONMENT,值设为Development/Production等;或在部署任务的「环境变量」中配置。 - GitHub Actions:在
env块中定义变量:jobs: deploy: runs-on: ubuntu-latest env: ASPNETCORE_ENVIRONMENT: Production steps: # 部署步骤...
环境变量覆盖配置核心逻辑
无需多配置文件的关键是利用环境变量覆盖appsettings.json的默认值。例如:appsettings.json中保留占位配置:
{ "ConnectionStrings": { "DefaultConnection": "placeholder-value" } }
在不同环境的流水线中,设置环境变量ConnectionStrings__DefaultConnection(用双下划线替代配置路径中的冒号),运行时环境变量会自动覆盖配置文件中的值。
目标2:从Azure Key Vault读取密钥
你的代码未生效是因为没有将Key Vault的秘密注入到配置系统中,正确实现步骤如下:
1. 安装依赖包
执行以下命令安装Azure Key Vault相关NuGet包:
dotnet add package Azure.Extensions.AspNetCore.Configuration.Secrets dotnet add package Azure.Identity
2. 配置Key Vault基础信息
在appsettings.json中添加空的Key Vault配置节点,避免硬编码敏感信息:
{ "KeyVaultConfig": { "KeyVaultUrl": "", "TenantId": "", "ClientId": "", "ClientSecret": "" } }
本地开发时,右键项目→「管理用户机密」添加这些值;部署时通过CI/CD流水线设置对应的环境变量(如KeyVaultConfig__KeyVaultUrl)。
3. 整合Key Vault到配置系统
修改配置加载逻辑,将Key Vault的秘密添加到配置体系:
var builder = WebApplication.CreateBuilder(args); // 加载基础配置 builder.Configuration .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddEnvironmentVariables(); // 读取Key Vault配置并整合 var keyVaultConfig = builder.Configuration.GetSection("KeyVaultConfig").Get<KeyVaultConfig>(); if (!string.IsNullOrEmpty(keyVaultConfig?.KeyVaultUrl)) { var credentials = new ClientSecretCredential( keyVaultConfig.TenantId, keyVaultConfig.ClientId, keyVaultConfig.ClientSecret); // 将Key Vault秘密注入配置系统,后续可直接通过Configuration读取 builder.Configuration.AddAzureKeyVault( new Uri(keyVaultConfig.KeyVaultUrl), credentials); } // 示例:从Key Vault读取数据库连接字符串并配置DbContext builder.Services.AddDbContext<AppDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
4. 配置Key Vault权限
确保ClientId对应的服务主体拥有Key Vault的「机密用户」权限,可在Azure Portal的Key Vault→「访问策略」中添加该权限。
内容的提问来源于stack exchange,提问作者The Inquisitive Coder

