Practical ASP.NET

Managing Web.Config Settings During Deployment

Moving from a test to a production environment can be tricky. Here's where the Web Deployment Projects add-on comes in handy.

You're probably using the web.config file to hold the connection strings for your Web site. But that makes it difficult to move from your test to your production environment, especially if you're deploying to a Web farm. The solution is to start using Web Deployment Projects.

I hold the connection strings for my databases in the connectionString element of my web.config file. In the test system, those configuration strings point to the test database, but when I move the application to the production system, I need those connection strings to point to my production database.

To make life more interesting, I also encrypt the connection strings in the web.config file rather than store them in plain text. For the encryption, the process uses the machine key for the server the Web site is installed on. But this means that if I encrypt the strings on my test machine, then the strings can't be decrypted on the production machine. Even more interestingly, some of my clients install their applications on Web farms. So, even if I deploy the application with the connection strings correctly encrypted for one production computer, those connection strings won't be encrypted correctly for any other server.


While I could, I assume, ask my clients to use the same machine key for all the servers in a Web farm, I use a different, two-part solution for this problem: Web Deployment Projects and deferring encryption until after the site is deployed.

Replacing and Encrypting Connection Strings
Web Deployment Projects are an add-on available for both Visual Studio 2005 and 2008 that addresses the special implementation issues of deploying ASP.NET projects. I'm not going to describe all the features of Web Deployment Projects, but the support for managing the web.config file was the primary reason that I started using Web Deployment Projects.

Web Deployment Projects allow you to enter a set of name/value pairs where the name refers to a section of the Web.config file and the value refers to a file containing replacement text for the section. For instance, this example replaces the connectionStrings element with the contents of a file holding production connection strings:

connectionStrings=ProductionConnectionStrings.config;

Since Web Deployment Projects provide a reliable way to swap in production-specific settings in my Web.config file during deployment, my next step is to ensure that the configuration strings aren't encrypted until the application is installed on the production machine.

If my client doesn't use a Web farm, the problem is simple: I can just swap in a file with connectionStrings containing the keys as encrypted on the production machine. However, a more robust solution (and one that works on Web farms) is to compile the connectionString section after the site is installed on the production machine. I handle that by putting the encryption code in the Load event of some page that I can be assured will be accessed early in the life of the site. Good choices are the site's login page or the site's Master Page.

In the encryption code, I check a tag in the appSetting section of the site's Web.config file to see if the site is in production or debug mode. The tag that I use looks like this:

<appSettings>
  <add key="Production" value="False" />
 </appSettings>

If the code finds that the Production appSetting is set to True, it opens the Web.config file, finds the connectionStrings section and encrypts it. As this example shows, I also set an Application variable indicating that I've encrypted the section and check that along with the appSettings entry so that I only do this once.

There's one last thing to do: In my Web Deployment project, I also replace the appSettings section of my Web.config file with a file that sets my "Production" appSetting tag to True to trigger encryption on the production site.

About the Author

Peter Vogel is a principal in PH&V Information Services, specializing in ASP.NET development with expertise in SOA, XML, database, and user interface design. His most recent book ("rtfm*") is on writing effective user manuals, and his blog on technical writing can be found at rtfmphvis.blogspot.com.

Reader Comments:

Fri, Aug 15, 2008 Peter Canada

I'm not sure that I see the security danger that's exposed by letting your own application have access to its web.config filebut that probably reflects my naive understanding of potential security breaches. However, all I can say is that I haven't had to make any changes to security settings to implement this solution.

I think that using the file attribute on tags in the config file to incorporate "satellite files" is an excellent solution and one I should have mentioned, at least in passing. However, I like having all my config settings on any machine in one file, which is what my method accomplishes. In the end, though, I'm effectively doing what the file attribute does: using multiple files and combining them to create the production config file.

I don't know that I can claim any significant benefits for doing it my way except that, should you need to change the settings in the satellite files you must use a different release process since the normal process doesn't update the satellite files. My method uses the same release process even if I'm changing the production settings. But how often do you need to change those production settings in the satellite file?

Thu, Aug 14, 2008 Robert Taylor Dallas

In the appSettings area of the web.config, you can apply the "file" attribute to that tag and include settings from an external config file. I usually will set it to something like "../Configuration/AppName.config" since it is relative. This way changes can be made to the app.config as you install new pieces, but the database connection strings can exist in a file that will not be touched when deploying. Also, if you deploy all of your projects to the same directory, they can all use the same external config file.

Something to think about...

Thu, Aug 14, 2008 jpcoder

Wouldn't this mean that you would have to give modify rights on your web.config to the network service account (or whatever you have the site running under)? That doesn't sound like a good idea from a security standpoint. Regardless of whether or not this is a good idea I didn't see you mention that you would need to give the necessary rights to the file.

Add Your Comments Now:

Your Name:(optional)
Your Email:(optional)
Your Location:(optional)
Comment:
Please type the letters/numbers you see above