Exercise 2: Exception Handling Strategies

In this exercise you will secure part of our application service with Code Access Security and then use a Replace Handler with the Exception Management Application Block to hide sensitive information from clients. You will also show how you can filter which exceptions escape the top application layer.

First step

  1. Open the Puzzler2.sln file, and build the solution.

View the Service Modifications

  1. Open DictionaryService.cs in the PuzzlerService project.
    You added a new class to the PuzzlerService project, named DictionaryService. This class acts as a Service Interface on top of the Dictionary class. Within this class you provide exception filtering and transformation before sending the results back to the client. For techniques to intercept the call and automatically transform and handle exceptions, see the "Developing Microsoft .NET Service-Oriented Applications" course of Mastering Industrial Strength .NET.

Protect the Service's 'Add Word' Functionality with Code Access Security

  1. Open Dictionary.cs in the PuzzlerService project. Find the AddWord method and decorate it with a security attribute as follows:
    [System.Security.Permissions.PrincipalPermission(System.Security.Permissions.SecurityAction.Demand, Role="Grand PoohBah")]                             
    public static Boolean AddWord(string wordToAdd)
    This method can now only be executed by a user who is a member of the role Grand PoohBah, an unlikely situation.
    Note: Decorate the AddWord method in Dictionary.cs not DictionaryService.cs.
  2. Run the application, type a nonsense word (alphabetic - no numbers!) into the 'Word To Check' textbox (ensure that you have an error flashing), then click on the Add Word button. This will call the service's AddWord function and throw a SecurityException, which you can check in the event viewer.
    The SecurityException may be serialized from a Server to a Client (over Web Services) and contains information that may help an attacker break our security. You would prefer to catch and log the security exception on the server, then pass an exception containing less information to the client.
  3. Close the application.

Configure the application to replace SecurityExceptions

  1. Run the Enterprise Library Configuration tool.  From the Windows Start menu select All Programs | Microsoft patterns and practices | Enterprise Library | Enterprise Library Configuration.

     

  2. Select File | Open Application and browse to the App.config file located here (in the ex02/begin/PuzzlerUI project).

     

    Note: Do not use any existing Application Configuration that you may already have open - this will be for the previous exercise. Ensure that you Open the App.config for Ex02!
  3. You have already created a policy, named Service Policy. By default, if a policy is empty, then exceptions will just be re-thrown inside the catch block, so in effect the policy will do nothing.
    Add a new Exception Type: System.Security.SecurityException to the Service Policy. Change the PostHandlingAction for the SecurityException to ThrowNewException.

     

  4. Add a new Logging Handler to the SecurityException exception type, and change the following values:
    LogCategory: General
    Title: Security Exception in Service Layer
  5. Add a Replace Handler for the SecurityException exception type. Change the ExceptionMessage to "Unauthorized Access", and select System.Security.SecurityException from mscorlib as the replacement exception type from the type selector dialog.
    Although you have kept the type the same, by creating a new SecurityException, this will not provide the client any of the stack information or internal security exception information, which could compromise security.

Change the Application to Exit on a Security Exception

  1. To add a new exception type under UI Policy of System.Security.SecurityException. Leave the PostHandlingAction as NotifyRethrow, which will cause the handler for the Application.ThreadException event to re-throw the exception, and shut down the application.
  2. Add a Logging Handler to the SecurityException under UI Policy, and change the property values to:
    LogCategory: General
    Title: Security Exception in UI Layer
  3. Save the current application in Enterprise Library Configuration using File | Save All.

Test the Replace Handler

  1. Run the application, type a nonsense (alphabetic) word into the Word To Check textbox (ensure that you have an error flashing), then click on the Add Word button. If debugging click on Continue when it displays an "Unhandled exception" message. Open the event log to look at the events created. You can use the debugger to observe exactly what is happening and relate this to the Exception Handling Policies.

     

    This time the Exception will be shown three times in the Event Log.
     
    First a SecurityException is captured in Dictionary.cs. This is caught by the service layer (DictionaryService.cs) which applies Service Policy. This will cause the exception to be written to the event log on the server (with all available information included) and then will capture a new replacement SecurityException (without specific stack information).
     
    Second the replacing SecurityException is caught by the Application ThreadException handler in Startup.cs. This applies UI Policy which will write the exception to the event log on the client (the same machine in our case) and set the re-throw boolean to true which allows our code to decide to re-throw the second SecurityException.
     
    Third the re-thrown SecurityException is caught by our AppDomain UnhandledException handler (it was thrown from outside the Application.Run) which applies Unhandled Policy. This will log the exception and display a MessageBox informing us that there was an error in the application.
     
    The AppDomain UnhandledException handler does not consume exceptions, so the exception continues to pass to the runtime or debugger exception handler. This will cause a standard unhandled exception dialog box to be displayed.