Skip navigation

When You’re Not Yourself, Impersonate!

Secure ASP.NET

 

When You re Not Yourself, Impersonate!

 

By Don Kiely

 

I recently completed courseware for AppDev that focuses on some advanced features of the .NET Framework 2.0. Several of the course sections I wrote deal with security; along the way I had to take a good look at impersonation. Because impersonation is frequently the subject of questions on the ASP.NET support forums at http://www.asp.net (of which I m a moderator), I thought this would be good fodder for a security column. I ve derived the material here from the AppDev course I wrote.

 

One of the most powerful things you can do with Windows identity objects in .NET is to impersonate another user for a short time. While the impersonation is in effect, the code executes with the security context of the impersonated user instead of the currently logged-in user. If it creates a file, the impersonated user owns the file. If the logged-in user has access to a SQL Server database, but the impersonated user doesn t, any attempt to connect to the database will throw a security exception.

 

By default, ASP.NET Web applications run under a special Windows account: MACHINE\NETWORK SERVICES in Windows Server 2003 and later and MACHINE\ASPNET in earlier versions of Windows. You can set up an ASP.NET application to be able to impersonate the actual user and perform actions with that user s security context.

 

Many of the examples of ASP.NET impersonation you find, particularly on MSDN, are quite complicated. This seems to have led many people to think that it is a complex operation. Although it is certainly an advanced technique, it isn t hard to do and the code is fairly simple. The sample application I discuss here starts running as the default ASP.NET process identity, then impersonates the current logged-in user. While impersonating the user, it creates a text file in the impersonated user s My Documents directory. Then the code will revert to the ASP.NET process identity. Along the way, it prints messages to the Web page about which identity is currently in effect. Below are the contents of the page when the sample runs (RIVERCHASER is the machine, of course).

 

Impersonation Sample

Current identity: RIVERCHASER\ASPNET

Impersonating RIVERCHASER\donkiely

Current identity: RIVERCHASER\ASPNET

 

To make this work, you must do a little setup once you ve created the ASP.NET project. First, create an IIS virtual directory that points to the directory containing the ASP.NET application. Impersonation won t work using the Cassini Web server that Visual Studio normally runs when you debug a Web site. The entire application runs with the logged in user s security credentials rather than that of either NETWORK SERVICES or ASPNET. This makes sense, because IIS is not involved when you use Cassini.

 

Next, change the authentication method for the virtual directory to Integrated Windows authentication only. By default, new virtual directories use both Windows and anonymous access. In the directory s property page s Directory Security tab, click the Edit button in the Anonymous access and authentication control section. Uncheck the anonymous option and leave the Windows Integrated authentication option checked.

 

Once you have the virtual directory set up, it s time to code. Create an ASP.NET application. Here I m using VB, but you can easily translate it to C#. Put all the code in the page s Load event procedure. You ll also need to import the System.IO and System.Security.Principal namespaces. After writing a page title, the code uses the shared GetCurrent method of the WindowsIdentity class to print the name of the current user under which the code is running. This will be the ASP.NET process identity:

 

Response.Output.Write("<h1>Impersonation Sample</h1>")

Response.Output.Write("<h4>Current identity: {0}</h4>", _

     WindowsIdentity.GetCurrent.Name)

 

Next, the code gets a reference to the current Windows principal. This is the user who is running the application, the impersonated user, switching the security context from the ASP.NET process account. The Page class in ASP.NET has a User property that returns an IPrincipal object directly so you don t have to use .NET Framework classes. The code then uses the Identity property to get the associated WindowsIdentity object, casting the IIdentity object returned from the Identity property to a WindowsIdentity object. It also instantiates a WindowsImpersonationContext object that we ll use later to revert the impersonation:

 

Dim prin As IPrincipal = Me.User

Dim iden As WindowsIdentity = _

     DirectCast(prin.Identity, WindowsIdentity)

Dim wic As WindowsImpersonationContext = Nothing

 

The code below calls the identity s Impersonate method, which kicks in the impersonation. It returns a WindowsImpersonationContext object used later to undo the impersonation:

 

wic = iden.Impersonate

 

Now the code in the page is running with the impersonated user s security context. It once again writes the user s name, which is no longer the ASP.NET process context. While still impersonating the user, it creates a text file in the user s My Documents directory:

 

Response.Output.Write("<h4>Impersonating {0}</h4>", _

     WindowsIdentity.GetCurrent.Name)

Dim path As String = _

     Environment.GetFolderPath( _

     Environment.SpecialFolder.MyDocuments) & "\text.txt"

File.WriteAllText(path, "Hello from " _

     & WindowsIdentity.GetCurrent.Name)

 

In the Finally block the code calls the WindowsImpersonationContext s sole custom method, Undo. This reverts the security context of the application to the ASP.NET process account. It once again writes out the current user s name to prove that the security context is once again that of the ASP.NET process account:

Finally

     wic.Undo()

End Try

Response.Output.Write("<h4>Current identity: {0}</h4>", _

     WindowsIdentity.GetCurrent.Name)

 

For fun, go ahead and run the application in Visual Studio, which uses Cassini by default. You ll find that you as the logged in user are displayed as both the current identity and the impersonated user. What a concept, impersonating yourself! Then try it for real. Use your favorite Web browser it doesn t have to be Internet Explorer, as long as it is a recent version of the browser and enter this URL:

 

http://localhost/appdev/default.aspx

 

You should see the page as shown above.

 

Now check the file that the page created while impersonating you. In Windows Explorer navigate to your My Documents directory and look for the text.txt file. Open it in Notepad or another text editor to see the content, which, when I ran it is:

 

Hello from RIVERCHASER\donkiely

 

But there s more to this than just some content. To prove that donkiely actually created and owns the file, open Windows Explorer. Right-click the file and select Properties from the pop-up menu. Select the Security tab and click the Advanced button in the lower right of the dialog box. This opens the Advanced Security Settings dialog box. Select the Owner tab and see that the impersonated user owns the file, rather than the ASP.NET process account (which wouldn t be able to write to my My Documents directory, anyway).

 

Impersonation is a powerful technique! You won t want to use it often because it is fraught with potential security risk, allowing a Web application to do things on a server as a user that is presumably more powerful than the ASP.NET process account. But when you need it, it can add some nice capabilities to your Web applications.

 

Don Kiely, MVP, MCSD, is a senior technology consultant, building custom applications as well as providing business and technology consulting services. His development work involves tools such as SQL Server, Visual Basic, C#, ASP.NET, and Microsoft Office. He writes regularly for several trade journals, and trains developers in database and .NET technologies. You can reach Don at mailto:[email protected] and read his blog at http://www.sqljunkies.com/weblog/donkiely/.

 

 

 

 

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish