机密管理
在开发环境中使用 .NET User Secrets 安全存储机密,在生产环境中使用 Azure Key Vault 或环境变量。
机密管理 是 CoddyKit 上的免费 C# Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C# Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C# Academy 课程共包含 4 节课。
机密信息不是普通配置
密码、API 密钥、连接字符串和 JWT 签名密钥绝不能存储在 appsettings.json 中,也不能提交到源代码管理。 .NET 提供了多种专门用于机密管理的机制。
用户机密(开发环境)
用户机密会在项目目录之外的本机文件中存储开发环境的机密信息。它们会在 Development 环境中自动加载,并且不会随源代码一起传递。
# Initialize (adds UserSecretsId to .csproj):
dotnet user-secrets init
# Set secrets:
dotnet user-secrets set "Database:Password" "dev-pass-123"
dotnet user-secrets set "Jwt:SigningKey" "dev-jwt-key-abc"
dotnet user-secrets set "OpenAI:ApiKey" "sk-..."
# List / remove:
dotnet user-secrets list
dotnet user-secrets remove "OpenAI:ApiKey"
# Stored at:
# macOS/Linux: ~/.microsoft/usersecrets/{id}/secrets.json
# Windows: %APPDATA%\Microsoft\UserSecrets\{id}\secrets.json显式加载用户机密
Host.CreateApplicationBuilder 会在 Development 环境中自动加载用户机密。您也可以在非 Development 场景或测试项目中显式加载它们。
var builder = Host.CreateApplicationBuilder(args);
// Automatic (Development only) — already done by default
// Equivalent manual call:
if (builder.Environment.IsDevelopment())
builder.Configuration.AddUserSecrets<Program>();
// In test projects (no ASPNETCORE_ENVIRONMENT):
var config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: true)
.AddUserSecrets<Program>() // loads secrets.json
.AddEnvironmentVariables()
.Build();用于生产环境的环境变量
在生产环境中,请将机密信息注入为环境变量——应用会在运行时从操作系统或容器编排器读取它们,而不会将明文机密与代码一起持久化到磁盘。
# docker-compose.yml — inject secrets:
services:
api:
image: myapp:latest
environment:
- Database__Password=${DB_PASSWORD} # from .env file
- Jwt__SigningKey=${JWT_KEY}
- ConnectionStrings__Default=Server=db;Password=${DB_PASSWORD}
# Kubernetes Secret:
kubectl create secret generic app-secrets \
--from-literal=Database__Password=secret123 \
--from-literal=Jwt__SigningKey=verylongkey
# Reference in pod spec:
# env:
# - name: Database__Password
# valueFrom:
# secretKeyRef: { name: app-secrets, key: Database__Password }Azure Key Vault 集成
Azure Key Vault 是用于生产环境的托管机密存储。官方提供程序会直接将机密加载到配置系统中,因此您的应用可以像读取其他配置值一样读取它们。
// dotnet add package Azure.Extensions.AspNetCore.Configuration.Secrets
// dotnet add package Azure.Identity
var builder = WebApplication.CreateBuilder(args);
if (!builder.Environment.IsDevelopment())
{
var kvUri = new Uri(builder.Configuration["Azure:KeyVaultUri"]!);
// Uses Managed Identity / workload identity in production:
builder.Configuration.AddAzureKeyVault(kvUri, new DefaultAzureCredential());
}
// Secrets named "Database--Password" in Key Vault
// are accessible as builder.Configuration["Database:Password"]
// (Key Vault uses -- as the : separator)AWS Secrets Manager
在 AWS 中,请使用 Amazon.Extensions.Configuration.SystemsManager 或直接使用 Secrets Manager,将机密注入 .NET 配置管道。
// dotnet add package Amazon.Extensions.Configuration.SystemsManager
builder.Configuration.AddSystemsManager(
path: "/myapp/production", // parameter store prefix
optional: false,
reloadAfter: TimeSpan.FromMinutes(30));
// Or Secrets Manager directly:
using Amazon.SecretsManager;
using Amazon.SecretsManager.Model;
var client = new AmazonSecretsManagerClient();
var response = await client.GetSecretValueAsync(new GetSecretValueRequest
{
SecretId = "myapp/production/db-password"
});
var secret = response.SecretString; // JSON string
// Parse and inject into configHashiCorp Vault
HashiCorp Vault 提供动态机密、机密轮换和细粒度访问控制。请使用社区提供的 VaultSharp 库或配置提供程序,将其集成到 .NET 中。
// dotnet add package VaultSharp
using VaultSharp;
using VaultSharp.V1.AuthMethods.Token;
var authMethod = new TokenAuthMethodInfo("vault-token");
var vaultClient = new VaultClient(
new VaultClientSettings("https://vault.example.com:8200", authMethod));
// Read a secret:
var kv = await vaultClient.V1.Secrets.KeyValue.V2
.ReadSecretAsync(path: "myapp/database", mountPoint: "secret");
var password = kv.Data.Data["password"].ToString();
// Then store in configuration or pass to IOptions:
builder.Configuration["Database:Password"] = password;保护内存中的机密
即使在内存中,也应谨慎处理机密信息。请使用 SecureString,或通过 using 块限制作用域,并避免记录机密值。
// NEVER log secrets:
_logger.LogInformation("API Key: {Key}", apiKey); // WRONG!
_logger.LogInformation("API Key configured: {HasKey}", !string.IsNullOrEmpty(apiKey)); // CORRECT
// Mask in diagnostics:
public string KeyHint => apiKey.Length > 8
? $"{apiKey[..4]}...{apiKey[^4..]}"
: "****";
// Scope the secret:
void ProcessWithSecret()
{
var secret = LoadSecret();
try { UseSecret(secret); }
finally { secret = string.Empty; } // clear reference
}CI/CD 中的机密
CI/CD 管道(GitHub Actions、Azure DevOps、Jenkins)提供机密变量存储。请在构建或部署时将机密注入为环境变量——绝不要将其硬编码在管道 YAML 中。
# GitHub Actions — store in Settings > Secrets:
# name: Deploy
# on: push
# jobs:
# deploy:
# runs-on: ubuntu-latest
# env:
# Database__Password: ${{ secrets.DB_PASSWORD }}
# Jwt__SigningKey: ${{ secrets.JWT_KEY }}
# steps:
# - name: Run migration
# run: dotnet ef database update
# Azure Pipelines:
# variables:
# - group: my-app-secrets # from Azure DevOps Variable Group
# The secrets are masked in logs and never stored in plaintext实战:开发环境/生产环境机密策略
一个完整的机密管理策略:开发环境使用用户机密,生产环境使用 Azure Key Vault,并以环境变量作为回退方案。
var builder = WebApplication.CreateBuilder(args);
if (builder.Environment.IsDevelopment())
{
// Dev: local secrets.json, never committed
builder.Configuration.AddUserSecrets<Program>();
}
else
{
// Production: Azure Key Vault via Managed Identity
var kvUri = builder.Configuration["Azure:KeyVaultUri"];
if (!string.IsNullOrEmpty(kvUri))
builder.Configuration.AddAzureKeyVault(
new Uri(kvUri), new DefaultAzureCredential());
}
// Always load env vars (works in all environments + containers):
// Already loaded by CreateBuilder — they override Key Vault
// Bind secrets to strongly typed options:
builder.Services
.AddOptions<JwtOptions>()
.BindConfiguration("Jwt")
.ValidateDataAnnotations()
.ValidateOnStart();快速检查
为什么绝不能将机密信息存储在 appsettings.json 中?
回顾:机密管理
要点:
- 绝不要将机密存储在
appsettings.json中——它会被提交到源代码管理 - 开发环境:使用用户机密(
dotnet user-secrets)——存储在项目之外 - 生产环境:使用环境变量、Azure Key Vault、AWS Secrets Manager 或 HashiCorp Vault
- CI/CD:将机密存储在管道的机密存储中,并注入为环境变量
- 绝不要记录原始机密值;请使用提示或掩码
- 组合使用多种策略:开发环境使用用户机密 + 生产环境使用 Key Vault + 环境变量覆盖
常见问题解答
「机密管理」课时是免费的吗?
是的 — 「机密管理」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C# Academy 课程的其余内容,请升级到 CoddyKit PRO。 C# Academy 课程共包含 4 节课。
「机密管理」这节课中我会学到什么?
在开发环境中使用 .NET User Secrets 安全存储机密,在生产环境中使用 Azure Key Vault 或环境变量。 你通过在浏览器中直接运行的动手代码来练习 C# Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 C# Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 C# Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「机密管理」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 C# Academy 课中编写并运行代码吗?
能。每节 C# Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。