记住不要在主目录中存储秘密appsettings.json
它位于网站中,通常保存在源代码管理中。使用文件提供程序将文件定位到服务器上其他位置的文件。
如果您有权访问 Azure,则可以将机密存储在Azure 密钥保管库代替appsettings.json
.
考虑到这一点,如果您想使用 JSON 文件,您可以使用桥或代理类来处理值的解密。
首先,您需要一个类来解密这些值。为了简洁起见,我不会在这里详细介绍解密类,只是假设一个名为SettingsDecryptor
已经编写并实现了一个名为ISettingsDecryptor
使用单个方法 Decrypt 来解密字符串值。
桥接类有两个构造函数参数。
- 第一个是
IOptions<T>
or IOptionsSnapshot<T>
其中 T 是该部分所在的类appsettings.json
绑定到通过services.Configure
方法(例如MyAppSettings
)。或者,如果您不想绑定到类,您可以使用IConfiguration
相反,直接从配置中读取。
- 第二个是解密类,实现
ISettingsDecryptor
.
在桥类中,每个需要解密的属性都应该使用解密类来解密配置中的加密值。
public class MyAppSettingsBridge : IAppSettings
{
private readonly IOptions<MyAppSettings> _appSettings;
private readonly ISettingsDecrypt _decryptor;
public MyAppSettingsBridge(IOptionsSnapshot<MyAppSettings> appSettings, ISettingsDecrypt decryptor) {
_appSettings = appSettings ?? throw new ArgumentNullException(nameof(appSettings));
_decryptor = decryptor ?? throw new ArgumentException(nameof(decryptor));
}
public string ApplicationName => _appSettings.Value.ApplicationName;
public string SqlConnectionSting => _decryptor.Decrypt(_appSettings.Value.Sql);
public string OracleConnectionSting => _decryptor.Decrypt(_appSettings.Value.Oracle);
}
DI 容器应该设置如下:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddOptions();
services.Configure<MyAppSettings>(Configuration.GetSection("MyAppSettings"));
services.AddSingleton(Configuration);
services.AddSingleton<ISettingsDecrypt, SettingsDecryptor>();
services.AddScoped<IAppSettings, MyAppSettingsBridge>();
}
然后控制器可以有一个构造函数,将桥接器作为IAppSettings
访问解密的设置。
上面的答案是整个解决方案的简要总结,因为需要相当多的代码。
完整详细的解释可以在我的博客文章中看到隐藏秘密appsettings.json– 在 ASP.Net Core 配置中使用桥(第 4 部分)我在其中详细描述了桥接模式的使用。 Github 上还有一个完整的示例(包括解密类):https://github.com/configureappio/ConfiguarationBridgeCrypto