Over the last couple of days we've talked about how to impersonate another user, and some security issues to keep in mind while impersonating. Now I'd like to take a look at some new features available in Whidbey which can make the whole process much nicer. I'm going to code this up in Visual Basic to take advantage of VB's ability to provide exception filters, which allow me to undo impersonation on the first pass of exception handling without actually catching the exception.
To start with, I'm going to make a SafeHandle wrapper around the user token, so that I gain all the benefits presented by the new SafeHandle model. (More information on SafeHandles here and here).
Now, I'll define a delegate that will be called under the impersonation context. The delegate takes a single parameter which is a generic type. The return value will also be generic.
For the actual work of the utility library, I'm going to have a static method that takes:
The return value of the method will be whatever the delegate returns. Essentially this method is a wrapper around the code exposed by the delegate which makes it run while impersonating. The code for this method is a pretty straightforward fallout of our last post.
Basically, we start by calling LogonUser. Then we begin impersonating and call the delegate. If the delegate were to throw, we undo the impersonation in the exception filter. If it doesn't throw, the finally block takes care of undoing impersonation.
Finally, this method would be made slightly easier to use if we provided an overload that defaulted the logon type to Interactive and the logon provider to DefaultProvider.
We can compile all of that infrastructure into a utility library. Using that library will make safely completing some work in an impersonated context pretty easy, especially when you take advantage of C#'s new support for anonymous delegates:
Perhaps a more real-world usage might be something like this: