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

.NET 6如何仅用单个appsettings.json并从Azure Key Vault取密钥

问题描述

我正在使用.NET 6,希望实现两个目标:

  1. 不再维护多个appsettings.{environmentname}.json文件,仅使用单个appsettings.json适配不同环境;
  2. 移除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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 22:35:27