ASP.NET: Delegate identity from a web application to a back end web application

August 08, 2008

...

One of the things that seem very simple on a Powerpoint presentation, but are not that simple in practice, is having a web user’s identity forwarded from a calling web application to another web application when using Kerberos.

The case is as follows: I have an intranet application A which uses Integrated Windows Authentication to authenticate the user. During processing of a request from a web users, application A then makes an HTTP request to intranet application B. Application B requires the web user to be authenticated to process the request. The often most attractive solution for solving this is what Microsoft refers to as identity delegation. Simple in a Powerpoint presentation, but alas, not so simple in practice.

First of all, there are a number of preconditions in the computing environment configuration that need to be fulfilled. I found a very good summary of gotchas in this respect here. In my case, the points 2 and 6 was missing (I knew about the other once beforehand). So, when all configuration stuff set up, then the only thing left is the code and configuration in the application A.

Basically, you need to make the application impersonate the web user (meaning that it will run with the credentials of the web user). There are two ways to do this. If you wish the entire request to run as the web user, you can insert an <identity impersonate=”true” /> element under <system.web> in the application’s web.config. Or, if you wish only the request to application B to run as the web user, you can do this programmatically:

using System.Security.Principal;
...
WindowsIdentity identity = (WindowsIdentity)HttpContext.Current.User.Identity();
using (identity.Impersonate())
{
    // ... code to call application B goes here ...
}

Then, the next task is to call application B itself. You can do this by creating a web request:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.somethingcompletelydifferent.com");
request.ImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Delegation;
request.UseDefaultCredentials = true;
...
HttpWebResponse response = request.GetResponse();
...

The important things to notice here is that we set the ImpersonationLevel property to “Delegation” and that we set the UseDefaultCredentials property to “true”. So, it together, we get:

using System.Security.Principal;
...
WindowsIdentity identity = (WindowsIdentity)HttpContext.Current.User.Identity();
using (identity.Impersonate())
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.somethingcompletelydifferent.com");
    request.ImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Delegation;
    request.UseDefaultCredentials = true;
    ...
    HttpWebResponse response = request.GetResponse();
    ...
}

You can then test that it works in application B by checking the name in HttpContext.Current.User.Identity.Name.


Profile picture

Written by Vidar Kongsli who is a software professional living in Oslo, Norway. Works as a consultant, system architect and developer at Bredvid. You should follow him on Twitter