应使用azure key vault或aws secrets manager等专业密钥服务托管敏感配置,而非硬编码于appsettings.json;.net 6+原生支持addazurekeyvault注入,需显式调用并授予应用get/list权限,密钥名禁用冒号和点号,推荐下划线分隔。

连接字符串硬编码在 appsettings.json 里等于裸奔
明文存数据库连接字符串,等于把钥匙挂门把手上。哪怕用 appsettings.json,只要没加密或隔离,部署到服务器后,任何能读取文件权限的人都能直接看到 Server=... 和 Password=...。.NET 不会自动加密配置节,它只负责加载——加载的是什么,就是什么。
- 别信“我只放测试环境”——配置文件常被误提交到 Git,CI/CD 流水线也可能意外暴露
-
IConfiguration读出来就是解密后的字符串,中间不经过任何保护逻辑 - Windows 上可用
aspnet_regiis.exe加密web.config,但对appsettings.json无效,它压根不支持
用 Azure Key Vault 或 AWS Secrets Manager 替代本地配置
这是目前最主流、也最省心的生产方案:把敏感值移出代码和配置文件,由专业密钥服务托管,应用启动时按需拉取。.NET 6+ 原生支持通过 AddAzureKeyVault 或 AddSecretsManager 注入配置源。
- 必须显式调用
builder.Configuration.AddAzureKeyVault(...),否则不会自动生效 - 需要给应用身份(如托管标识或 Service Principal)授予 Key Vault 的
Get和List权限,缺一不可 - Key Vault 中的密钥名不能含冒号或点号(如
ConnectionStrings:Default会失败),建议用下划线,比如ConnectionStrings_Default - 本地开发时可配合
UserSecretsId使用,但仅限开发机,不能替代生产密钥服务
自己加密 connectionStrings 节?小心 .NET 的配置合并机制
有人想用 AES 加密整个 connectionStrings 节再 Base64 存进 JSON,启动时手动解密赋值——这看似可控,实则容易踩坑。因为 IConfiguration 是只读快照,且多源配置会合并,你手动改 ConfigurationRoot 内部结构,可能被后续配置源覆盖或引发竞态。
- 不要尝试反射修改
ConfigurationRoot._providers或替换IConfigurationSection实例 - 如果坚持自加密,应在
Program.cs最早阶段(var builder = WebApplication.CreateBuilder(args)之后、builder.Build()之前)解密并写入内存配置提供者:builder.Configuration.AddInMemoryCollection(new Dictionary<string string> { ["ConnectionStrings:Default"] = decryptedValue })</string> - 密钥和 IV 必须安全存储(如环境变量或 Key Vault),绝不能硬编码在代码里,哪怕只是“临时测试”
- .NET 7+ 的
ISecretManager接口仍处于预览状态,不建议在生产中依赖
环境变量方式最轻量,但要注意大小写和平台差异
把连接字符串设为环境变量(如 ConnectionStrings__Default),.NET 配置系统会自动映射到 ConnectionStrings:Default。它不需要额外库,也不依赖外部服务,适合中小项目或容器化部署。
- Linux/macOS 下环境变量名全小写,
connectionstrings__default也能被识别;Windows 不区分大小写,但统一用大写更稳妥 - 双下划线
__是层级分隔符,不是两个下划线加空格,也不是点号——写成ConnectionStrings:Default当环境变量名会完全失效 - Docker 中用
-e "ConnectionStrings__Default=..."传入,注意 shell 对特殊字符(如@、$)的转义,建议用单引号包裹整个值 - 环境变量优先级高于
appsettings.json,但低于命令行参数——如果你在 CI 脚本里混用,可能被意外覆盖
真正麻烦的从来不是“怎么加一层密”,而是密钥本身怎么保管、谁有权访问、轮换时怎么不影响服务。哪怕用了 Key Vault,如果托管标识权限开太大,或者日志里不小心打印了 IConfiguration 全量内容,照样白搭。











