在.NET中使用User Secrets(用户机密)

.NET中的User Secret(有时也叫机密管理)功能到现在已经很久了(好像从.NET Core 2.0开始)。鼓励开发者把邮件、Slack、Teams的密码或全部保密文件发出去。我也不明白开发者在本地能有什么秘密不能和团队共享的。因此,一个集中式的的机密储存应用更受欢迎,比如Azure Keyvault。

但是在过去的几个月中,我看到了它们的价值。现实中,我用User Secret主要为了“它在我的设备上是为本地开发工作的”,而不是真正的机密。

接下来我们看看User Secrets是怎么工作的,以及我们可以怎样使用它,然后再聊聊用它做了什么。.

一、通过Visual Studio创建User Secrets

目前为止,使用User Secrets最简单的方式是通过VS。右键单击你的项目,选择“Manage User Secrets”。

在.NET中使用User Secrets(用户机密)

然后VS就自行安装、设置机密文件!

需要准备一个空的机密文件,我们稍后会说。

二、通过命令行创建

我们也可以通过命令行创建User Secrets!需要在我们的项目文件夹里运行下列命令:

dotnet user-secrets init

运行后会产生guid,会放在你的csproj文件里差不多是这样的:

6272892f-ffcd-4039-b82a-b60874e91fce

你也可以自己生成guid并放到文件里,只需要在你设备的项目中添加,只不过guid必须是唯一的。当然,如果你想让项目共享机密,可以在不同的项目中使用相同的guid。

到此,你就通过命令行设置了机密。

在notepad编辑机密文件之前,你需要先通过命令行创建一个机密。所以,在你的项目文件夹里执行下列命令:

dotnet user-secrets set"MySecret""12345"

Windows中,会生成文件,文件路径是这样的:

%APPDATA%\Microsoft\UserSecrets\{guid}\secrets.json

在Linux中,文件如下:

~/.microsoft/usersecrets/{guid}/secrets.json# 打开这个文件,会看到类似这样的内容:{    "MySecret":"12345"}

从这儿开始,就可以在notepad中编辑文件了,实际上,你也可以手动创建这个文件,不使用命令行。但是需要注意,这个文件在你添加第一个机密之前,是不存在的。如果在你的csproj文件里有一个用户秘密guid,但是没有对应文件,那就会报错。

综上,使用VS可以很简单的实现所有的工作。

但是命令行可以帮你了解这个文件存储在哪里,以及它在你的设备是怎样存在的。

三、在.NET配置中使用User Secrets

User Secrets在.NET中的配置模式与其他一样。所以如果你用appsettings.json, Azure Keyvault,Environment Variables等等,整体操作都是一样的。

1、先安装Nuget包:

Install-Package  Microsoft.Extensions.Configuration.UserSecrets

2、配置服务

这里取决于你用mini API,还是用.NET 5的普通方式。比如在.NET 6 minimal API中,大概是这样的:

builder.Configuration.AddEnvironmentVariables()                     .AddKeyVault()                     .AddUserSecrets(Assembly.GetExecutingAssembly(),true);

那在普通模式里,可以对应的修改就行。

注意,我给AddUserSecrets的第二个变量用了“true”。因为.NET 6中,User Secrets是默认“强制”的,所以设置为“true”把它变成可备选的。如果用户还没有在设备中配置机密文件,那就会报错。特例如下:

System.IO.FileNotFoundException:The configuration file 'secrets.json' was not found andisnot optional

现在,User Secrets已经在我们的配置中加载了。理想情况下,我们需要最后把User Secrets放到配置中,因为意味着这是最后一次覆盖。

四、User Secrets的优缺点

我觉得与命名相反,User Secrets对秘密并不友好,除非用户特殊配置。举个例子。我之前一个控制台应用程序中,只有一个开发人员没用Windows系统。这样很好,因为我们有本地文件路径配置,在Windows系统也很顺利。但是Linux用户就出现了问题。最开始,这个开发人员下载了项目、修改了配置文件,运行项目也没问题。到检查工作的时候,需要快速恢复或忽略配置文件的改动,所以没有push。当然,这种情况不常见,code review发现时,会建立对应的git功能分支,修改也会被push。

现在我们看同一个例子。这个Linux开发人员只是简单改了User Secrets文件路径,用于适配他们的设备。从没动过appsettings.json,一切正常。

再说一个我参与的另一个团队。他们过去曾在Azure中使用共享远程数据库进行本地开发。当开发人员编写或SQL迁移时,会导致各种各样的麻烦。迁移会打断其他开发人员。为了不打断其他开发人员的工作,我创建了User Secrets,并向团队展示了他们如何覆盖默认的SQL连接字符串,转而使用他们的本地开发设备,这样我们就可以慢慢地远离使用共享数据库。