Impersonation

All right, now that I have done a bunch of talking, how about some code? I stumbled across this recently while pouring through MSDN. The code lets you impersonate any other user, provided you know the credentials. In our case we needed to become the IIS user so we could access files on a remote file server. In our situation, there are multiple web applications within our domain, so the network admin has set up the IIS sites to all use a common domain-wide anonymous user, so it is easier for him to manage permissions. As we are the first .Net project, the ASPNet user has no rights whatsoever on the network. We talked with the admin and he was not interested in giving the ASPNet users from a bunch of different web servers rights to other network resources. We looked at changing the ASPNet user credentials Machine.config, but this broke debugging locally immediately. So I looked into impersonation and found out how to impersonate the IIS user in code:

Imports System.Security.Principal

Function impersonateAnonymous() As WindowsImpersonationContext

     ‘Grab the current Http context
    
Dim context As HttpContext = HttpContext.Current

    ‘Set up a Service Provider based on this context
     Dim
iServiceProvider As iServiceProvider = CType(context, iServiceProvider)

     ‘Create a type which represents an HTTPContext
     Dim
httpWorkerRequestType As Type = GetType(HttpWorkerRequest)

     ‘Get the HttpWorkerRequest service from the service provider
     Dim
workerRequest As HttpWorkerRequest = _
         
CType(iServiceProvider.GetService(httpWorkerRequestType), HttpWorkerRequest)

     ‘Get the token passed by IIS from the workerRequest service
     Dim
ptrUserToken As IntPtr = workerRequest.GetUserToken()

     ‘Create a Windows Identity from the token
     Dim
winIdentity As New WindowsIdentity(ptrUserToken)

    ‘Send back the IIS identity
     Return
winIdentity.Impersonate

End Function

To use the function, simply call it like so before the code that needs proper permissions:

Dim impContext As WindowsImpersonationContext = impersonateAnonymous()

Now the subsequent lines of code operate in the context of the user assigned to IIS. And then when you are done impersonating:

impContext.Undo()

I based this function on some C# code I found in a Patterns & Practices document on MSDN: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetsec/html/thcmch10.asp