我找到了一个在安装here期间加密web.config的示例,但我的应用程序是一个Windows服务。 aspnetreg_iis
方法仅适用于web.config文件。
我知道如何以编程方式加密配置文件,但我不认为我可以使用WiX做到这一点。我错了吗?有什么想法吗?
答案 0 :(得分:4)
以下是我最终的结果...
我使用WiX和DTF创建了一个托管代码Custom Action来加密配置文件的给定部分:
public static void EncryptConfig(Session session)
{
var configPath = session["APPCONFIGPATH"];
var sectionToEncrypt = session["SECTIONTOENCRYPT"];
var fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = configPath;
var configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
ConfigurationSection section = configuration.GetSection(sectionToEncrypt);
if (!section.SectionInformation.IsProtected)
{
section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");
section.SectionInformation.ForceSave = true;
configuration.Save(ConfigurationSaveMode.Modified);
}
}
我提到这个问题时缺乏理解的部分原因是不知道您可以使用DTF在托管代码中安全地创建自定义操作。 DTF上的文档很少,但是一旦你开始工作,就很棒了。
我发现只有在InstallFinalize之后安排自定义操作时,这才有效。
这是实现它的WiX配置:
<InstallExecuteSequence>
<Custom Action="EncryptConfigurationFiles" After="InstallFinalize" />
</InstallExecuteSequence>
<Fragment>
<Binary Id="YourProject.CustomActions.dll" SourceFile="$(var.YourProject.CustomActions.TargetDir)$(var.YourProject.CustomActions.TargetName).CA.dll" />
<CustomAction Id="EncryptConfigurationFiles" BinaryKey="YourProject.CustomActions.dll" DllEntry="EncryptConfig" Return="check" />
</Fragment>
这些博客/网站帮助我实现了目标,上面的大部分代码都源于它们:
http://geekswithblogs.net/afeng/Default.aspx http://blog.torresdal.net/2008/10/24/WiXAndDTFUsingACustomActionToListAvailableWebSitesOnIIS.aspx http://blogs.msdn.com/jasongin/archive/2008/07/09/votive-project-platform-configurations.aspx
@PITADeveloper ...感谢您的回复。我发现我不需要加载程序集来加密配置文件。
如果你使用它,你应该使用try catch并返回一个ActionResult ......上面是伪代码。
最后,我正在使用DataProtectionConfigurationProvider。对于RSA提供商,我认为还有更多的环节可以跳过。
我希望这有助于某人!
答案 1 :(得分:3)
您应该可以在自定义操作中执行此操作。我发现的问题是为ExeConfigurationFileMap加载程序集会引发异常,但您可以通过向AppDomain添加AssemblyResolve处理程序来处理它。这是一种来自我使用机器加密密钥加密/解密受保护配置部分的富客户端应用程序的hack-up。它可能不是最漂亮的代码,但我希望你能从中得到它的图片。此代码假定您在配置文件中定义了要使用的ProtectionProvider。
//class global
static System.Reflection.Assembly DefiningAssembly;
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);
static System.Reflection.Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)
{
return DefiningAssembly;
}
然后,您可以像这样加载配置:
DefiningAssembly = System.Reflection.Assembly.LoadFrom("path to defining assembly for config");
//Set the Configuration using an ExeConfigurationFileMap - This works for any .config file.
ExeConfigurationFileMap CfgMap = new ExeConfigurationFileMap();
CfgMap.ExeConfigFilename = "path to config file";
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(CfgMap, ConfigurationUserLevel.None);
List<string> DefiningAssemblyTypes = new List<string>();
foreach (System.Type type in DefiningAssembly.GetExportedTypes())
{
DefiningAssemblyTypes.Add(type.Name);
}
foreach (ConfigurationSection tempSection in config.Sections)
{
if (DefiningAssemblyTypes.Contains(tempSection.ElementInformation.Type.Name))
{
section = tempSection;
break;
}
}
ProtectionProviderName = section.SectionInformation.ProtectionProvider.Name;
section.SectionInformation.ProtectSection(ProtectionProviderName);
config.Save(ConfigurationSaveMode.Minimal, true);
我希望这能帮到你,祝你好运。