How do I encrypt app.config file sections during install with WiX?

余生长醉 提交于 2019-12-09 16:50:39

问题


I have found an example for encrypting a web.config during installation here, but my app is a windows service. The aspnetreg_iis method works only for web.config files.

I know how to programatically encrypt the config file, but I don't think I can do that using WiX. Am I wrong? Any ideas?


回答1:


Here is what I ended up with...

I used WiX and DTF to created a managed code Custom Action to encrypt a given section of a config file:

    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);

        }
    }

Part of my lack of understanding that prompted this question was not knowing that you can safely create custom actions in managed code using DTF. Documentation is sparse on DTF, but once you get it working, it is great.

I found that this only worked if I scheduled the custom action after InstallFinalize.

Here is the WiX config to make it happen:

<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>

These blogs/sites helped me get there and much of the code from above was derived from them:

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... Thanks for the response. I found that I did not need to load the assembly to encrypt the config file.

If you use this, you should use a try catch and return an ActionResult... The above is pseudo-code.

Finally, I'm using the DataProtectionConfigurationProvider. For the RSA Provider, I think there are a couple more hoops to jump through.

I hope this helps someone!




回答2:


You should be able to do it within a custom action. The catch that I've found is that loading an assembly for an ExeConfigurationFileMap will throw an exception, but you can handle that by adding an AssemblyResolve handler to the AppDomain. This is kind of a hack-up from a rich-client app I wrote to encrypt/decrypt protected configuration sections using a machine encryption key. It's probably not the prettiest code, but I'm hoping you can get the picture from it. This code assumes that you have the ProtectionProvider you want to use defined in the config file.

//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;
}

Then, you can load your configuration like this:

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);

I hope this helps you, best of luck.



来源:https://stackoverflow.com/questions/306992/how-do-i-encrypt-app-config-file-sections-during-install-with-wix

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!