Practical ASP.NET

Encrypting the WebConfig (A Return)

Peter Vogel returns to encrypting web.config files in subfolders and encrypting non-standard sections. Sort of everything you wanted to know about encrypting the web.config file but were afraid someone would tell you.

Back in June of last year I covered the basics of encrypting portions of your web.config file. Encrypting your config file ensures that should evil people get hold of it -- and it often has all sorts of sensitive information in it, including connection strings with passwords -- they would be unable to use the information it contains.

Recently, a reader who wanted to go beyond these basics got in touch with me (thanks, Angelika!). The reader wanted to encrypt the web.config files in subfolders in the Web site and to encrypt a wider variety of elements in the config file than I had addressed (principally, the mailSettings element). On the assumption that if one person is interested, others must be, here's how to do those things, including how to retrieve any section within your web.config file.

First: accessing the web.config file in subfolders. In the original article, I used this code to point a Configuration object at a web.config file so that I could encrypt sections within it:

Dim configFile As System.Configuration.Configuration 
configFile = System.Web.Configuration.WebConfigurationManager. _
      OpenWebConfiguration(Request.ApplicationPath)

To access a web.config file in a subfolder, you only need to append the folder name (with a forward slash) to the ApplicationPath property of the Request object. This code, for instance, retrieves the web.config file in a subfolder called "User":

configFile = System.Web.Configuration.WebConfigurationManager. _
      OpenWebConfiguration(Request.ApplicationPath & _
	"/User")

Second: Accessing elements in the config file. There are several mechanisms that you can use to retrieve a section. In the previous column, I used the Sections collection of the Configuration object, passing the name of the section that I wanted to retrieve. This is the code I used to retrieve the connectionStrings section, for instance:

Dim configSection As ConfigurationSection 
configSection = configFile.Sections("connectionStrings")

If you're after either the AppSettings or ConnectionStrings section (and you really should be encrypting those sections), then you can use dedicated properties on the Configuration class, like this:

configSection = configFile.AppSettings
configSection = configFile.ConnectionStrings

Using the Sections collection, as I did, lets you retrieve about twenty additional sections (not all of which seem to be relevant to ASP.NET -- the "windows" section is included in this collection, for instance). Unfortunately, if you want to encrypt a section not included in the Sections collection then you'll have to use a third mechanism.

For instance, the mailSettings section that my reader wanted to encrypt is one of the sections not available through the Sections collection. A typical mailSettings element would look like this:

<system.net>
  <mailSettings>
    <smtp deliveryMethod="Network" 
          from="[email protected]">
      <network defaultCredentials="false" 
 	     userName="admin" password="fred"/>
    </smtp>
   </mailSettings>
</system.net>

It's easy to see why you'd want to encrypt this element: it holds the userName and password for a mail account, which is the kind of information you want to keep away from evil people.

To retrieve this section (or, in fact, any section in the web.config file), you can use the Configuration object's GetSection method, passing the "path" to the section you want. You might think, therefore, that this code will retrieve the mailSettings element:

configSection = configFile. _
   GetSection("system.net/mailSettings")

You would be wrong, but only because I've been misleading you: mailSettings is a SectionGroup, not a Section. The code you need to retrieve mailSettings looks like this:

Dim configSectionGroup As ConfigurationSectionGroup 
configSectionGroup = configFile. _
     GetSectionGroup("system.net/mailSettings")

However, SectionGroups can't be encrypted. To encrypt the smtp element, which actually is a Section, you'll have to drill down one more layer (which is where all the sensitive data is, anyway). That code looks like this:

configSection = configFile. _
   GetSection("system.net/mailSettings/smtp")

SectionGroups aren't completely useless in this process. If you wanted to encrypt (or otherwise process) all of the members of a SectionGroup, retrieving the SectionGroup would be very useful. This code, for instance, retrieves the SectionGroup and then processes each Section it contains:

For Each sect As ConfigurationSection _
         In configSectionGroup.Sections
   ...process section
Next

This isn't the best example that I could have used: The mailSettings element is only allowed to hold a single smtp element.

The final step in this process is to encrypt the section. The code that I used in the previous column still works:

configSection.SectionInformation. _
 ProtectSection("RsaProtectedConfigurationProvider")

I suspect that I've now exhausted this topic: You've got the tools to encrypt any web.config file on your site and to access (and encrypt) any section in those files. But, if that's not enough, drop me a line and we can return to this topic.

About the Author

Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at http://blog.learningtree.com/tag/ui/.

comments powered by Disqus

Featured

Subscribe on YouTube