动态解密配置,包括实体框架的连接字符串
本文关键字:框架 连接 字符串 实体 包括 解密 配置 动态 | 更新日期: 2023-09-27 18:16:52
在谷歌搜索了一段时间后,我找不到任何合适的解决方案来解决我的问题:我加密了我的app.config,所以我在我的appSettings部分得到如下条目:
<add key="Modules" value="xx+LCaY//dRSq3H5z0TClbQbIUd1fm4krjTelMWu9bwkBB2SybkwMqAchYiLP7ss1EEotHtrZwrVtuc+1la5aVwUebCMMbPUj3reE+1XY1Q=" />
此外,我有格式为
的连接字符串<add name="WorkflowEntries" connectionString="NEuhdfCDdGOeGjkk5PvMDl/Zr+75rOSDqifQZE3X6WJ6ZKjqG6J75O8d0b0j1AeXLVMGtkN7oPldtAWqppFKwCliJ+baMA2NVbkpLlMbhc/IH771MWjlC588USC8RzB7lz+BuXas4RS8kkDXmjENDAlEecLYA2nnkMFlXHJxCCOGA35JXTXWHZeQlFU0dBHVJlSUbqTEGTPETqe2tq/WQMfVpRHsLWlrReBplvGYqVZ+T8XTgaJellN0ZJY4f/UV9R2gjOOwvkBUxRJ2djymlbs4nek/oLuTKyCstd5sRluux8V2odplc98ehmVO0KJ0fBFHIzm4qjByj5pke+kc9FsYSTcqQ4KbBbuXwFI1Oc/1wORHOJbZlu40jioAXVDNiCZQh57cm40G9CRJNAE2Ww=="
providerName="System.Data.EntityClient" />
我可以围绕ConfigurationManager构建一个包装器。AppSettings和ConfigurationManager。ConnectionStrings,但EF不会使用它。是否有一种方法可以"虚拟地操纵"配置,以便应用程序的所有部分都可以访问该配置?
提示:我知道受保护配置的力量。因为我需要轻松地部署我的应用程序,所以这不是我的选择。
我想我完成了。欢迎你发表更多我认为一定存在的有说服力的解决方案。我创建了一个CustomConfigurationManager,将所有需要的逻辑放入其中。你可以这样做:
-
类是静态的,所以只需在以下情况下调用CheckConfig()方法您的应用程序启动将检查密钥"加密"appSettings。如果它已经存在,什么也不会发生,否则一切都是的连接字符串connectionStrings部分被加密。密钥"加密"将
将被添加到配置中以防止下次启动时应用程序再次加密配置。 在复制-粘贴操作中,我替换了所有出现的ConfigurationManager。AppSettings由CustomConfigurationManager.AppSettings。当从配置(如CustomConfigurationManager.AppSettings["SampleKey"])读取值时
最关键的部分是将CustomConfigurationManager和Entity Framework结合在一起。我通过手动替换上下文类中的构造函数来做到这一点。在这个过程中,我使用了CustomConfigurationManager。ConnectionStrings indexer .
让我们仔细看看最后一步:
<add name="WorkflowEntries" connectionString="NEuhdfCDdGOeGjkk5PvMDl/Zr+75rOSDqifQZE3X6WJ6ZKjqG6J75O8d0b0j1AeXLVMGtkN7oPldtAWqppFKwCliJ+baMA2NVbkpLlMbhc/IH771MWjlC588USC8RzB7lz+BuXas4RS8kkDXmjENDAlEecLYA2nnkMFlXHJxCCOGA35JXTXWHZeQlFU0dBHVJlSUbqTEGTPETqe2tq/WQMfVpRHsLWlrReBplvGYqVZ+T8XTgaJellN0ZJY4f/UV9R2gjOOwvkBUxRJ2djymlbs4nek/oLuTKyCstd5sRluux8V2odplc98ehmVO0KJ0fBFHIzm4qjByj5pke+kc9FsYSTcqQ4KbBbuXwFI1Oc/1wORHOJbZlu40jioAXVDNiCZQh57cm40G9CRJNAE2Ww=="
providerName="System.Data.EntityClient" />
构造函数
public partial class WorkflowEntries : ObjectContext
{
#region Constructors
public WorkflowEntries()
: base("WorkflowEntries", "WorkflowEntries")
{
this.ContextOptions.LazyLoadingEnabled = true;
OnContextCreated();
}
...
是
public WorkflowEntries()
: base(CustomConfigurationManager.ConnectionStrings["WorkflowEntries"], "WorkflowEntries")
{
this.ContextOptions.LazyLoadingEnabled = true;
OnContextCreated();
}
如果你不想操作上下文类,你也可以在实例化上下文时使用接受连接字符串的重载。
这是我的CustomConfigurationManager类。请注意,我删除了加密和解密部分,因为我认为它们与这个问题的上下文中无关。
public static class CustomConfigurationManager
{
private static string pwd = "ThisIsNotBestPracticeForStoringPasswords".Select(x => x.ToString() + (x + 2).ToString()).Aggregate((current, next) => current + next);
public static AppSettingsIndexer AppSettings = new AppSettingsIndexer(pwd);
public static ConnectionStringsIndexer ConnectionStrings = new ConnectionStringsIndexer(pwd);
public static void CheckConfig()
{
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
var appSettings = config.AppSettings;
var connectionStrings = config.ConnectionStrings.ConnectionStrings;
if (!appSettings.Settings.AllKeys.Contains("Encrypted"))
{
EncryptConfig(pwd, config, appSettings, connectionStrings);
}
}
private static void EncryptConfig(string pwd, Configuration config, AppSettingsSection appSettings, ConnectionStringSettingsCollection connectionStrings)
{
foreach (var key in appSettings.Settings.AllKeys)
{
appSettings.Settings[key].Value = StringCipher.Encrypt(appSettings.Settings[key].Value, pwd);
}
for (int i = 0; i < connectionStrings.Count; i++)
{
connectionStrings[i] = new ConnectionStringSettings(connectionStrings[i].Name, StringCipher.Encrypt(connectionStrings[i].ConnectionString, pwd), connectionStrings[i].ProviderName);
}
appSettings.Settings.Add("Encrypted", "True");
config.Save(ConfigurationSaveMode.Modified, true);
}
static class StringCipher
{
internal static string Encrypt(string plainText, string passPhrase)
{
if (plainText.Trim() == "")
return "";
/* Add your encryption stuff here */
}
internal static string Decrypt(string cipherText, string passPhrase)
{
if (cipherText.Trim() == "")
return "";
/* Add decryption stuff here */
}
}
public class AppSettingsIndexer
{
static string pwd;
public AppSettingsIndexer(string _pwd)
{
pwd = _pwd;
}
public string this[string index]
{
get
{
return StringCipher.Decrypt(ConfigurationManager.AppSettings[index], pwd);
}
}
}
public class ConnectionStringsIndexer
{
static string pwd;
public ConnectionStringsIndexer(string _pwd)
{
pwd = _pwd;
}
public string this[string index]
{
get
{
var connectionString = ConfigurationManager.ConnectionStrings[index];
return new ConnectionStringSettings(connectionString.Name, StringCipher.Decrypt(connectionString.ConnectionString, pwd), connectionString.ProviderName).ToString();
}
}
}
}