lthough originally envisaged as a product for use in Windows Forms (executable) applications, Enterprise Library is proving popular with Web application developers as well. For example, the Data Access Application Block, the Cryptography Application Block, the Exception Handling Application Block, and the Logging Application Block provide useful features that can considerably simplify development of complex applications.
Some blocks, such as the Caching Application Block, contain features that are also supported directly by ASP.NET; however these can sometimes prove useful in specific scenarios. For example, unlike the ASP.NET Caching mechanism, the Caching Application Block allows the simultaneous use of both a sliding and an absolute expiration time for cached values. The Security Application Block also offers a more flexible approach for features such as authorization and security credential caching than ASP.NET if you need to roll your own mechanisms.
The main issue in the past has been that many features of Enterprise Library work only in Full Trust mode, whereas many Web applications must run in lower trust modes. In particular, Medium Trust is a popular choice, because it limits the permissions of many features of ASP.NET and the .NET Framework that could compromise operations, while still not limiting the functionality of the code too severely.
To resolve this issue, the Microsoft patterns & practices (p& p) group has released a patch for Enterprise Library that lets you use it more easily in partial trust mode. The patch replaces some of the Enterprise Library source code to change its behaviors, including:
- Removal of most assembly-level permission demands. The default installation of Enterprise Library?January 2006 version?makes demands for all the permissions required for a block at the assembly level, which causes loading of that assembly to fail in non-Full Trust scenarios. The patched version allows assemblies to load?but you are then responsible for writing code that fails gracefully when a code access security exception arises. This occurs only in a few isolated places, such as instrumentation calls that write to the Event Log.
- Permission demands defined within the code. Where code within Enterprise Library requires additional permissions, the demands are implemented within the code at that point (either in Enterprise Library code or in the base .NET class libraries), and limited to the features that require the permissions. Therefore, security exceptions will arise only when those particular code sections execute.
- Graceful performance degradation. Where possible, code that demands permissions fails gracefully when the requested permissions cannot be granted, instead of generating an outright failure. For example, if the Logging Application Block is unable to call the API that provides information about the current process, the process information is simply left out of the message it generates and logs.
|Author’s Note: The patch does not add the AllowPartiallyTrustedCallersAttribute to the Enterprise Library assemblies. As a result, it does not support situations where a partially trusted application attempts to use the Enterprise Library blocks and code as fully trusted. The patch does support situations where both the application and the Enterprise Library are running under partial trust.|
Obtaining and Installing the Partial Trust Patch
To obtain the Partial Trust Patch, you must join the community at the GotDotNet Web site. Follow the Patches link and download the zip file for Partial Trust Patch (2554).
The zip file contains the updated source code files only, so you must copy them over the existing files in your Enterprise Library source installation, and then recompile it.
|Author’s Note: Applying the patch overwrites a number of existing source files with new versions. If you have modified the Enterprise Library source code or unit tests to suit your own specific requirements, you must manually reconcile your changes with the changes included in the patch. Therefore, you should back up your original source code before applying the patch, and use a tool such as the Windiff utility to determine which files are different from the original files to ensure your changes are not overwritten by files included in the patch. You should run the suite of unit tests after applying the patch to ensure that the modified library still compiles and runs correctly.|
To apply the patch, extract the files from the zip file, maintaining the folder structure within it, and then copy the Src and UnitTests folders over the existing Src and UnitTests folders installed with Enterprise Library. The default installation location for Enterprise Library is %Program Files%Microsoft Enterprise Library January 2006.
After copying the new files, run the “Build Enterprise Library” and “Copy Assemblies to bin Folder” utilities from the Enterprise Library section of your Start menu to recompile all the source code and then copy the updated assemblies into the runtime bin folder. Ensure that the recompilation runs without reporting any errors.
The patch zip file contains an HTML document that describes the patch in detail, and lists the blocks and features that require special permissions when running in any mode other than Full Trust. The patches affect selected features of all six blocks, plus the configuration system and the instrumentation built into Enterprise Library. The tables at the end of the HTML document list and describe the affected features, and show the permission you must grant for each one. The document also lists known issues for the patch.
For an overview of Enterprise Library and details of the installation and initial configuration process, see the article “An Introduction to Enterprise Library.”
Configuring ASP.NET Applications with Partial Trust
Having updated your Enterprise Library installation, the next step is to configure your application(s) to run under one of the four partial trust modes?High, Medium, Low, and Minimal. Medium trust is the common choice; this section describes the process for enabling this mode. You can use the approach described in this section for the other modes as well, but you use the appropriate trust files for those modes instead.
|Figure 1. ASP.NET Configuration: The figure shows the architecture of the trust and configuration files for ASP.NET.|
Figure 1 shows the architecture of the trust and configuration files that control the security mode in ASP.NET. The application’s Web.config file can contain a
... Medium, Low, and Minimal definitions here ...
The root Web.config file also defines the default trust level for all ASP.NET applications running on the machine. You can see the
- Add the
> element to your application’s Web.config file and specify the relevant value for the level attribute (see Figure 1) to set the trust level just for that application.
- Edit the
element in the root Web.config file to specify the relevant value for the level attribute to set the trust level for all applications on the machine
However, this will not allow all the features of Enterprise Library to execute. The permissions granted in Medium Trust mode are too restrictive for some features of Enterprise Library, including:
- Reading information from configuration files
- Writing to performance counters, the Windows Event Log, and raising WMI events
- Serializing and encrypting data
- Accessing OLE-DB, Oracle, and ODBC databases (though the SqlClient provider for SQL Server will work in Medium Trust mode)
- Obtaining Windows Identity information within the Security Application Block
- Tracing, file listeners, and formatting features of the Logging Application Block
If you want to use any of these features (described in detail in the documentation for the Partial Trust Patch), you must add the grant permissions within the policy definitions file for the trust level under which you run the application. However, Microsoft strongly recommends that you should not edit the default policy definitions files provided with the .NET Framework. Instead, you should create a custom trust level policy definition by copying of one of the original policy definitions files and adding the required permission grants to the new copy.
Creating a custom trust level and implementing it within your applications involves five steps:
- Edit the root Web.config file to specify the location and name of your custom policy definitions file.
- Create the custom policy definitions file that grants the required permissions to ASP.NET applications to allow the features you want to use from Enterprise Library to execute.
- Specify the new custom trust level for your application, or for all applications running on the machine.
- Configure your application to use the required features from Enterprise Library
- Edit the application configuration file to prevent Enterprise Library requiring full trust permissions.
The following sections describe these steps in detail.
Creating a Custom Trust Level
The first step in creating a custom trust level is to specify the name and location of the policy definitions file. Following the approach taken by the .NET Framework, edit your root Web.config file by adding the new custom
... Medium, Low, and Minimal definitions here ...
The next step is to create the custom policy definitions file. The easiest way to create the new file is to make a copy of one of the original files. In almost all cases, you will want to grant extra permissions to your code, over and above the defaults defined by the chosen trust level. To do that, copy the file for your chosen trust level?in this case the file web_mediumtrust.config. Rename the copy to custom_mediumtrust.config, and open it with a text editor or the Visual Studio 2005 XML file editor.
Looking Inside a Policy Definition File
Policy definition files, such as the one you are about to edit, can contain more than one version of the policy level, however those provided with the .NET Framework contain only a single version defined with the
element contains a list of the permission classes referenced in the element, including the name and the .NET Framework class that implements that permission set.
element contains a list of the permissions for each of the classes listed in the element.
- A series of
elements that contain mappings between the permission classes and the specific permissions required by the .NET Framework.
In general, you will be concerned only with the first two sections. In the first, add the classes for which you want to set permissions that are not already included (such as permission to access an OLE-DB data source, encrypt data, or write to the Windows Event Log). In the second, add individual permission definitions for these classes and the classes already listed in the first section.
Adding Extra Security Permission Classes
... more security classes here ...
You can add other permission classes for which you want to grant permissions. For example, this listing shows how you can add the OleDbPermission, EventLogPermission, and DataProtectionPermission classes:
Notice how each definition in the code above specifies the assembly containing the class, the version, culture, and the public key token. Also note that the contents of the Description attribute should be all on one line, not wrapped to fit the page width as shown here. See the tables at the end of the HTML document provided with the Partial Trust Patch for a list of the permissions required by Enterprise Library when not running in Full Trust mode.
Granting Specific Security Permissions
Having added security classes to the
... ... more permission sets here ... ... more security permissions here ...
The preceding configuration shows how the .NET Framework specifies settings for ASP.NET. For example, under the Medium Trust?setting, ASP.NET must be able to read certain environment variables and access an application’s own folders (declared as $AppDir$) to execute successfully.
If the policy definition file already contains a definition for the permission you want to grant or change, you simply edit the existing
To permit access to any printer, edit the file to change the Level attribute value:
To use the features of Enterprise Library, you’ll usually have to modify the existing
To use the serialization features of the .NET Framework, something that occurs in several places within Enterprise Library, you must add permission to use serialization formatters by appending the SerializationFormatter flag:
In addition to updating existing
For example, earlier you saw how to add the OleDbPermission, EventLogPermission, and DataProtectionPermission classes to the
Notice how you can use the properties of the OleDbPermission class, through attributes in the
The custom policy definitions file can also specify permission grants for the two other classes, EventLogPermission, and DataProtectionPermission, previously shown added to the
To allow ASP.NET to access the .NET data encryption and decryption features when using the Cryptography Application Block, you use the DataProtectionPermission class. This
|Author's Note: To discover the permission classes you need to configure, use the tables at the end of the Partial Trust Patch HTML document. To find the properties of these and other security classes you want to configure, look up that class in the .NET SDK. The list of members shows the public properties. Following the links for a property should provide a list of valid values for that property?you can use these as attribute values in the
Specifying the Custom Trust Level in the Application
The final step is to specify the new custom trust level you created for the ASP.NET application, or for all ASP.NET applications running on the machine. To specify that an application should run under the new custom trust level, named CustomMedium, you add this attribute to its Web.config file:
To specify that all ASP.NET applications on the machine should run under the new CustomMedium trust level, edit the
Running an ASP.NET Application in Custom Medium Trust Mode
After you configure a suitable trust mode, and specify it in your Web.config file, you can add the Enterprise Library blocks you want to use in your application. Run the Enterprise Library Configuration Console from your Start menu and open the Web.config file for your site or application into the console. Use the right-click context menus to add the blocks, and configure them using the properties displayed in the right-hand window of the console. When complete, save the updated Web.config file.
|Author's Note: For details of using the Configuration Console to configure an ASP.NET application, and how the example used in this section uses the Enterprise Library application blocks, see the article "Working with Enterprise Library in ASP.NET."|
To run in any of the partial trust modes, Enterprise Library requires you to add the attribute requirePermission="false" to the individual
|Author's Note: In the preceding code, some type names and assembly names have been removed or abridged for clarity.|
However, one issue to be aware of is that you must manually edit the Web.config file after creating it with the Enterprise Library Configuration Console, and every time you update it using the Configuration Console, to add the requirePermission="false" attribute. In the current version of Enterprise Library (the January 2006 release), the Configuration Console removes the requirePermission="false" attribute from each
All applications should guard against the effects of exceptions arising (including security permission exceptions) for reasons not directly connected with the trust mode. For example, your code may reference a folder that has incorrect file read/write permissions set in the Access Control List (ACL), or attempt to access a network resource for which it does not have permission because the server has been reconfigured.
However, permission exceptions are more likely to occur when you run in a partial trust mode. The major changes you may need to make to your application when using Enterprise Library in less than Full Trust mode are to ensure you handle all possible security (and other) exceptions, and manage them gracefully.
Running the Example Application in Partial Trust Mode
To see the effects of partial trust on the Enterprise Library application block features, and how a custom trust level allows Enterprise Library to run in partial trust modes, the following shows an example application that uses the Caching Application Block, Data Access Application Block, Logging Application Block, and Cryptography Application Block.
|Figure 2. Security Exception in Medium Trust Mode: Medium Trust mode causes a security exception for the OLE-DB provider in the Data Access Application Block and for the Logging Application Block.|
The first stage is to add a
Running the application now generates a security exception because the right-hand list box uses the OLE-DB provider to access a database and populate the list. In Medium Trust mode, the OLE-DB provider does not have permission to execute, and raises an OleDbPermission exception (see Figure 2).
Notice also that the error message indicates a second exception. The code to populate the right-hand list box contains in the Catch section a call to the methods of the Logging Application Block. This should create an entry in Windows Event Log if an error occurs. However, in Medium Trust mode, Enterprise Library does not have permission to write to the Event Log, and so the .NET code access security mechanism raises an EventLogPermission exception.
The example lets you create and cache a DataSet generated from a table in the database by the Data Access Application Block. The code to generate the DataSet uses the SqlClient provider, and so will run in Medium Trust mode. However, the Caching Application Block is configured to use the Isolated Storage cache backing store in this example, which uses the .NET serialization features to serialize the data to disk. In Medium Trust mode, attempting to use serialization creates a SecurityPermission exception, as you can see in Figure 3.
|Author's Note: Isolated Storage is not an ideal caching mechanism for ASP.NET applications, but it serves to demonstrate the behaviour of trust modes for this example. In a future article, I'll show you how to create your own custom cache backing store provider that can store the cached data using a more suitable mechanism.|
The example page also demonstrates use of the Cryptography Application Block by allowing you to generate a hash for a string value, and encrypt and decrypt a string value using the Rijndael algorithm. While you can create hash values in Medium Trust mode, you cannot encrypt or decrypt data. Figure 4 shows the result of attempting to encrypt the string in the text box above the Get Hash, Encrypt, and Decrypt buttons. The .NET Framework code access security system raises a DataProtectionPermission exception.
Running the Example in a Custom Partial Trust Mode
To enable the data encryption/decryption features, and still allow Enterprise Library features to execute in partial trust, you must create a custom policy definitions file that contains the required permission grants, and then specify that as the trust mode for your application. In fact, the example application requires only one modification to existing permissions and the three extra permission grants shown earlier in this article. The Caching Application Block requires permission to serialize data:
Meanwhile, the Data Access Application Block, Logging Application Block, and Cryptography Application Block require new permissions added to the custom policy definitions file:
|Figure 5. Applying Custom Trust Mode: In the custom trust mode, the OLE-DB provider can execute using the specified connection string.|
To force the application to run under the new trust mode requires only a change to the
Using the custom trust mode, the application opens without any errors. You can see the data retrieved from the database in the right-hand list. The OLE-DB provider can run using the connection string specified in the policy definitions file (see Figure 5).
Clicking the button to create and cache a DataSet also works fine with the extra permission grant that allows the Caching Application Block to serialize the data before writing it to Isolated Storage. You can see in Figure 5 that the page indicates one item was added to the Caching Application Block cache. Click the button to load the DataSet back from the cache, and you see the data displayed in a GridView control on the page (see Figure 6).
The custom trust mode and the corresponding permissions specified by the CustomMedium policy definitions file also allow the Cryptography Application Block to encrypt and decrypt data. Clicking the Encrypt button generates the encrypted version of the text in the text box above the buttons, and displays it in the text box below the buttons (see Figure 7).
The encrypted data is stored in the Isolated Storage cache (using the Caching Application Block), and retrieved and decrypted when you click the Decrypt button. You can see how the Cryptography Application Block returns the original text, and displays in the lower text box (see Figure 8).
Setting OLE-DB Provider and Event Log Permissions
So far, you have seen how the custom permissions allow the Data Access Application Block, Caching Application Block, and Cryptography Application Block to execute correctly in a custom partial trust mode. This final section shows how the limited OLE-DB permission specified in the policy definitions file, and the permission grant required by the Logging Application Block, work in this custom trust mode.
|Figure 9. Permission Denied Exception: Using a non-permissible connection string raises a security exception.|
This is a good way to prevent unauthorized access to databases when using OLE-DB. For example, if you change the connection string that the Data Access Application Block uses for the OLE-DB provider, the code access security mechanism will raise a security exception:
This non-permissible connection string causes the .NET Framework to raise an OleDbPermission exception when the code runs?before it even attempts to connect to the specified database, as you can see in Figure 9.
|Figure 10. Accessing the Event Log with Custom Trust Mode. The Logging Application Block can access the Event Log in custom trust mode.|
Notice also that the error message indicates that the Logging Application Block successfully added an entry to Windows Event Log. The
|Author's Note: The Logging Application Block may fail to write events to the Event Log if it is full, and the time before overwriting events prevents old events being deleted. You should ensure that the Application Event Log is not full before running the example to ensure that new entries can be written to the log.|
You've now seen how easy it is to generate custom security policies for your ASP.NET applications, and use them to allow the features from Enterprise Library that would normally fail because of security exceptions to execute on your server. In other words, making these custom security policy changes extends the features of the Enterprise Library beyond just Windows applications, making them usable in your ASP.NET applications as well.