One of the greatest strengths of the .NET environment is the flexibility that standard XML configuration files bring. For example, an ASP.NET application receives application-specific settings from a web.config file. The file, if unmodified, will inherit the settings from the machine.config file that controls the default settings for all applications on the machine.
By default, the developer can change the way applications interact with ASP.NET by changing settings in the web.config file stored in the application’s root directory. For example, you may want to ensure any Web application placed in production takes advantage of a shared state server. Simply configure the machine.config files on each of the servers in your Web farm with the sessionState mode attribute set to StateServer instead of the default of InProc.
This may be a boon for the developer, but it’s a potential nightmare for the system architect. Consider this state management example. Unless the application developer changes the default web.config file generated by the new project wizard in Visual Studio, the local web.config file will always default to InProc. When the application is deployed on the server farm, it won’t take advantage of the state server, but instead each server will maintain its own state. In order to make sure that predetermined production standards are honored by all deployed applications, the .NET Framework provides two mechanisms for enforcing machine.config settings.
Option 1: Lock down all machine.config settings
The .NET Framework allows you to change the default behavior from allowing settings to be overridden in web.config files to preventing web.config changes from taking effect. Simply add an allowDefinition attribute to the section that you want to prevent a web.config file from overriding. For example, the default machine.config file contains a sessionState section like this:
type="System.Web.SessionState.SessionStateSectionHandler, System.Web, . . ."
By setting allowDefinition to “MachineToApplication,” the system will allow web.config files located in the root directory or any subdirectory marked as an application. Given this default, a developer can deploy an application overriding our machine.config default of StateServer contained in the system.web section of the machine.config file. In order to prevent this, set allowDefinition to “MachineOnly” instead of “MachineToApplication.” If you make this change, any attempt to load an application that tries to override the default settings will cause the common language runtime (CLR) to raise an exception, and the application will terminate automatically.
Option 2: Lock down settings by virtual directory
For many of the settings, this all-or-nothing approach won’t suffice. To apply more granular control, the .NET Framework allows you to specify machine.config settings that can’t be overridden at the virtual directory level—just use a location attribute within the machine.config file. For example, suppose you want all sites to default to StateServer, but you want to allow a specific application named ThisBoxOnly to run from a single server in the Web farm and use InProc session state. Your machine.config file would look like this:
<location path=”Default Web Site/ThisBoxOnly” allowOverride=”false”>
. . . />
. . ./>
Now the ThisBoxOnly site will use InProc session state while other sites will use the StateServer by default. By setting the allowOverride attribute to false, you can prevent the developer from overriding the values for the ThisBoxOnly application.
Locking down the production boxes
Of course, all of this work will be worthless if you don’t properly configure the security on your production servers. Only operations personnel should have the necessary permissions to modify the default machine.config files. You’ll also have to put processes in place to add the appropriate <location> elements in the production machine.config files for all servers in the Web farm if you want to use this per application directory method.