Impersonation inside HttpHandlers

About impersonating your ASP.NET code

By using basic or integrated IIS security, you can set the security context on whose behalf the code is running to the current user by adding these two lines in your web.config:

<authentication mode="Windows"/>
<
identity impersonate="true"/>

This can be usefull when you want to call WebServices inside you code that needs the current user's credentials (note: you'll need Kerberos authentication not to run into the two-hop problem, see http://blogs.msdn.com/mjeelani/archive/2004/12/07/275921.aspx).

The problem: No impersonation inside HttpHandlers

While your pages and controls will now run on behalf of the current user, for some reason this impersonation is not done inside your custom HttpHandler! Although the user is authenticated (HttpContext.Current.User.IsAuthenticated is true), all code is still running as ASPNET or the default AppPool identity (just add a watch on System.Security.Principal.WindowsIdentity.GetCurrent()). So by calling a WebService inside your HttpHandler code using the DefaultCredentials, the wrong credentials will be passed and you'll probably get a 404. 

The solution: Do your own impersonation

public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
{
  ...

  // Create a WindowsImpersonationContext object by impersonating the Windows identity.
  WindowsImpersonationContext impersonationContext = ((WindowsIdentity)context.User.Identity).Impersonate();
 
  try
  {
   
    //
    // Your impersonated calls to WebServices here
    //
  }
  catch {}
  finally
  {
    if (impersonationContext != null)
    {
      // always undo impersonation
      impersonationContext.Undo();
    }

  }


  ...

...so, after you impersonate to the identity inside the current HttpContext, your code will now be running on behalf of the currently logged on user, and you can call WebServices using the current user's credentials.

4 Comments

  • thanks, this will be useful.

  • You need to hold on to the ImpersonationContext so you can Revert when you're done. That way you you'll get a cleaner programming model.

  • aak! dude! tell them how to stop impersonating after making the calls too man!



    something like WindowsIdentity.Undo in a try finally block...!



    be careful submitting code like this out into the wild ***without addressing the security implications***

  • For readability reasons I don't normally put try/catch statements in my example code, but this time you guys may be right.

    So I've added a impersonation Undo statement inside a finally block.

Comments have been disabled for this content.