使用github的朋友经常会遇到这么个问题,由于仓库是public的,所以存储在配置文件内的数据库字符串等用户机密密钥会随代码push到代码仓库后被公开,即使你立即发现后删除配置文件,其他用户仍能从你的提交记录中查询到该机密数据,这肯定是我们所不想看到的,因此,微软为.NetCore的Appsettings文件提供了一种开发环境下的机密数据管理方案。
机密管理器工具的工作原理
机密管理器工具隐藏实现详细信息,例如值的存储位置和存储方法。 可以在不知道这些实现详细信息的情况下使用该工具。 这些值存储在本地计算机用户配置文件文件夹中的 JSON 文件中:
# Windows
%APPDATA%\Microsoft\UserSecrets\<user_secrets_id>\secrets.json
# Linux/macOS
~/.microsoft/usersecrets/<user_secrets_id>/secrets.json
在以上文件路径中, <user_secrets_id>
将 替换为 UserSecretsId
项目文件中指定的值。
不要编写依赖于使用机密管理器工具保存的数据的位置或格式的代码。 这些实现详细信息可能会更改。 例如,机密值不会加密,但将来可能会加密。
启用机密存储
机密管理器工具对用户配置文件中存储的特定于项目的配置设置进行操作。
机密管理器工具在 .NET Core SDK init
3.0.100 或更高版本中包含命令。 若要使用用户机密,请运行项目目录中的以下命令:
# .Net CLI
dotnet user-secrets init
或者在Visual Studio2019内,右键配置文件所在的项目,点击管理用户机密:

上述操作在项目文件的 PropertyGroup
内添加 UserSecretsId
元素。 默认情况下的内部文本是 UserSecretsId
GUID。 内部文本是任意的,但对于项目是唯一的。
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<UserSecretsId>79a3edd0-2092-40a2-a04d-dcb46d5ca9ed</UserSecretsId>
</PropertyGroup>
设置机密
定义由键及其值组成的应用机密。 机密与项目的值 UserSecretsId
相关联。 例如,从项目文件存在的目录中运行以下命令:
dotnet user-secrets set "Movies:ServiceApiKey" "12345"
机密管理器工具也可以用于其他目录。 使用 --project
选项提供项目文件存在的文件系统路径。 例如:
dotnet user-secrets set "Movies:ServiceApiKey" "12345" --project "C:\apps\WebApp1\src\WebApp1"
也可以通过在Visual Studio2019右键项目点击管理用户机密,在IDE内打开secrets. json 文件,然后在内部进行编辑:
{
"Movies": {
"ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
"ServiceApiKey": "12345"
}
}
读取机密
如常在.NetCore应用程序代码中使用Configuration对象来读取配置文件就可以了:
Configuration["Movies:ServiceApiKey"];
这里会优先读取机密文件也就是 secrets. json 内配置的对象节点,如果机密文件内不存在则读取appsettings内的配置,
不需要额外配置,因为在 Program.cs内的CreateDefaultBuilder方法调用的Host.CreateDefaultBuilder(args)为你自动加载机密文件了:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
如果你的项目没有使用 Host.CreateDefaultBuilder(args) ,那么你可以使用以下方式加载用户机密文件:
public class Program
{
public static void Main(string[] args)
{
var host = new HostBuilder()
.ConfigureAppConfiguration((hostContext, builder) =>
{
// Add other providers for JSON, etc.
if (hostContext.HostingEnvironment.IsDevelopment())
{
builder.AddUserSecrets<Program>();
}
})
.Build();
host.Run();
}
}
因为secrets.json不在项目文件夹内,所以避免机密数据了被git等版本管理工具提交到代码仓库的窘境,其他更加详细的内容请移步微软官方文档。