37

I have a web application with a custom configuration section. That section contains information I'ld like to encrypt (was hoping to use ASPNet_RegIIS rather than do it myself).

Web.Config:

<?xml version="1.0"?>

    <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
      <configSections>
          <section name="MyCustomSection" 
                   type="MyNamespace.MyCustomSectionHandler, MyAssembly"/>
    </configSections>
<configProtectedData>
    <providers>
      <clear />
      <add name="DataProtectionConfigurationProvider"
           type="System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, Version=2.0.0.0,
                   Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a,
                   processorArchitecture=MSIL"
           keyContainerName="MyKeyContainer"
           useMachineContainer="true" />
    </providers>
  </configProtectedData>
    <MyCustomSection>
       <blah name="blah1">
          <blahChild name="blah1Child1" />
       </blah>
    </MyCustomSection>

The configuration handler works great before trying to encrypt it. When I try to encrypt it with:

aspnet_regiis -pef "MyCustomSection" c:\inetpub\wwwroot\MyWebsite -prov DataProtectionConfigurationProvider

I get an error:

Encrypting configuration section... An error occurred creating the configuration section handler for MyCustomSection: Could not load file or assembly 'MyAssembly' or one of its dependencies. The system cannot find the file specified. (c:\inetpub\wwwroot\MyWebsite\web.config line 5)

I have tried with/without the provider configured. With/without section groups. With/Without having started the website before hand. I've tried temporarily putting my assembly in the GAC for the registration. I also tried my log4net section just to try something that wasn't mine, with no luck. I've run the command prompt as Administrator. Any ideas? Or can ASPNet_RegIIS just not be used for custom sections?

One final shot after viewing MSDN was changing my handler to inherit from ConfigurationSection rather than implementing IConfigurationSectionHandler since it was technically deprecated in 2.0 (hoping it was something regarding aspnet_regiis version). No luck there either.

Any ideas let me know. Thanks!

John Hoven
  • 4,085
  • 2
  • 28
  • 32
  • I got the same issue. I don't suppose there is a way to get this working without putting the assembly in the gac or the hack in the answer below? – Colin Mackay Jul 16 '09 at 16:24
  • I was tired of fiddling with it - so I just went with putting the assembly in the gac temporarily. – John Hoven Jul 16 '09 at 21:23

5 Answers5

38

aspnet_regiis must be able to bind the assembly. The normal .net binding rules apply.

I get around this by creating directory called aspnet_regiis_bin in the same directory as aspnet_regiis.exe and an aspnet_regiis.exe.config file with aspnet_regiis_bin as a private path like this:

<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <probing privatePath="aspnet_regiis_bin"/>
      </assemblyBinding>
   </runtime>
</configuration>

I then copy the assemblies that define the custom configuration sections into aspnet_regiis_bin so that aspnet_regiis can find them.

This procedure doesn't require the assemblies to be strong named or in the GAC but does require messing around in the framework directories.

hwiechers
  • 14,583
  • 8
  • 53
  • 62
19

I am using a workaround whereby I temporarly comment out the contents of the configSections element:

<configSection>
    <!--
    <section name="CustomSection" type="" />
    -->
</configSection>

You can then run the encryption using aspnet_regiis -pef as usual. After this has run just uncomment the section and your site is ready to run.

Mathew Paxinos
  • 944
  • 7
  • 16
  • Thank you. I was able to automate the process by using your suggestion (some Powershell comments out the section name, then aspnet_regiis runs and then the comments are removed again via Powershell). – Stefano Ricciardi Sep 10 '14 at 13:49
4

For the record, I ended up with a little maintenance page to do this for me.

var currentConfig = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~/");
// Unprotect
ConfigurationSection section = currentConfig.GetSection("MyCustomSection");
if (section.SectionInformation.IsProtected)
{
   section.SectionInformation.UnprotectSection();
   currentConfig.Save();
}

// Protect
if (!section.SectionInformation.IsProtected)
{
     section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");
     currentConfig.Save();
}

Caveats: Your process will need write access to the config files being modified. You'll want some way to authorize who can run this. You'll generally restart the website when you Save.

Community
  • 1
  • 1
John Hoven
  • 4,085
  • 2
  • 28
  • 32
4

This is a total hack, but I'm not sure that there's another way to do it without strongly naming the assembly that defines your custom section and GACifying it (although you mentioned that didn't work, either, and I'm not sure why it wouldn't). Since aspnet_regiis runs in the < drive >:\Windows\Microsoft.Net\Framework\< version > folder (in WinXP), you can copy the DLL that defines your config section into the relevant Framework\< version > folder, and then it should work.

AJ.
  • 16,368
  • 20
  • 95
  • 150
  • 1
    It was signed with a strong name when I moved it into the GAC. I also made sure to include the version/culture/public key in my configuration/section.type. Your solution did get me through though, thank you. If anyone else ever encounters this I ended up moving the dll to the framework folder as the answer suggests then running aspnet_regiis as administrator (Windows Server 2007). – John Hoven Apr 24 '09 at 20:40
  • After more fiddling around I got it to register from the GAC. I never tried registering to the GAC and using the long form in the type at the same time (though I did both at separate times). After thinking about it, it makes perfect sense that the assembly would be required to be in the GAC. Thanks again. – John Hoven Apr 24 '09 at 21:21
  • Awesome. I was having some trouble with this too. – Ronnie Overby Aug 05 '09 at 20:12
  • Correct answer. Also, if you are using runtime qualification of the assemblies, aspnet_regiis will not honor that. The section declaration itself must contain the fully qualified name of the assembly. See my separate answer for sample config entries that work, and ones that don't work. – Philippe Jan 23 '12 at 20:06
  • Could you please answer http://stackoverflow.com/questions/786661/using-aspnet-regiis-to-encrypt-custom-configuration-section-can-you-do-it ? – LCJ Mar 02 '12 at 06:20
2

The answer that is shown as correct is correct. I wanted to add a comment but could not because this is too long of a comment (sample config entries).

The section name should use the full name of the assemblies. A runtime assembly qualification does not work with aspnet_regiis.exe.

This WORKS:

<configSections>
  <section name="securityConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Security.Configuration.SecuritySettings, Microsoft.Practices.EnterpriseLibrary.Security, Version=5.0.414.0, Culture=neutral, PublicKeyToken=9c844884b2afcb9e" />
</configSections>

But this DOESN'T WORK:

<configSections>
  <section name="securityConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Security.Configuration.SecuritySettings, Microsoft.Practices.EnterpriseLibrary.Security" />
</configSections>

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
     <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.Security" fullName="Microsoft.Practices.EnterpriseLibrary.Security, Version=5.0.414.0, Culture=neutral, PublicKeyToken=9c844884b2afcb9e" />
    </assemblyBinding>
</runtime>
Philippe
  • 4,088
  • 4
  • 44
  • 49