mic*_*l81 7 c# asp.net runtime machinekey
对于IIS托管的ASP.NET MVC 4网站,我想在运行时期间在代码中动态调整机器密钥.
机器密钥,加密和验证密钥以及要使用的算法都存储在数据库中.web.config
我想在应用程序启动期间注入这些值,而不是从文件中读取值,而是让系统使用它们.
有没有办法实现这一点而不必改变web.config
(只改变内存配置)?
我试过访问配置部分,但它被标记为只读并且也是密封的,所以我无法覆盖IsReadOnly()
.但是,setter
对我来说,有一个指示器可能有一种方法可能会删除readonly标志.
var configSection = (MachineKeySection)ConfigurationManager.GetSection("system.web/machineKey");
if (!configSection.IsReadOnly())
{
configSection.ValidationKey = _platformInfo.MachineKey.ValidationKey;
configSection.DecryptionKey = _platformInfo.MachineKey.EncryptionKey;
...
}
Run Code Online (Sandbox Code Playgroud)
有没有办法实现这个目标?我能看到的唯一选择是使用像AppHarbor这样的自定义方法,但是如果可能的话,我宁愿坚持使用内置方法.
如果有人问为什么我想这样做,原因是,这是针对在webfarm中运行的大量相同网站.因此,必须具有非自动生成的密钥(在每个服务器上必须相同).此外,每个网站都应该是隔离的,不应该共享相同的密钥.由于所有网站的物理表示相同,因此它们共享相同的物理位置.这就是web.config文件不能包含特定于应用程序的设置的原因.
编辑:至少确认是否根本不可能,这将是非常有帮助的.如上所述,可以使用自定义验证和加密方法,这些方法将完全避免使用机器密钥设置.谢谢.
这很丑陋,但是我能够使用反射将config部分中的只读位暂时删除,设置密钥,然后恢复它:
var getter = typeof(MachineKeySection).GetMethod("GetApplicationConfig", BindingFlags.Static | BindingFlags.NonPublic);
var config = (MachineKeySection)getter.Invoke(null, Array.Empty<object>());
var readOnlyField = typeof(ConfigurationElement).GetField("_bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
readOnlyField.SetValue(config, false);
config.DecryptionKey = myKeys.EncryptionKey;
config.ValidationKey = myKeys.ValidationKey;
readOnlyField.SetValue(config, true);
Run Code Online (Sandbox Code Playgroud)
一旦Web应用程序启动,就无法以编程方式设置此项.但是,仍然可以实现您的目标.
如果每个应用程序都在其自己的应用程序池中运行,并且每个应用程序池都有自己的标识,请检查applicationHost.config中的CLRConfigFile开关.您可以使用此每个应用程序池来注入新级别的配置.有关如何使用它的示例,请参阅http://weblogs.asp.net/owscott/archive/2011/12/01/setting-an-aspnet-config-file-per-application-pool.aspx.您可以在每个应用程序池的自定义CLR配置文件中设置显式且唯一的<system.web/machineKey>元素.
这与Azure网站,GoDaddy和其他需要基于每个应用程序设置默认显式计算机密钥的主机使用的机制相同.请记住为每个将要访问它的应用程序池适当地对每个目标.config文件进行ACL.
归档时间: |
|
查看次数: |
6244 次 |
最近记录: |