Introduction

The term "Impersonation" in a programming context refers to a technique that executes the code under another user context than the user who originally started an application, i.e. the user context is temporarily changed once or multiple times during the execution of an application.

The reason for doing this is to perform tasks that the current user context of an application is not allowed to do. Of course you could grant the user executing an application more privileges, but usually this is a bad idea (due to security constraints) or impossible (e.g. if you don't have full administrative access to a machine to do so).

This article presents an easy-to-use class to impersonate a user. While writing this, I found out that Marc Merrit had written an article ("Windows Impersonation using C#") that uses the same Microsoft knowledge base code (from Q306158) that I have used. The code presented in my article differs in the fact that you could use it inside a using-block to safely release resources and that I use slightly more exceptions to report errors. But from a first look, both his and my article do the same job, so it's up to you to decide what to do.

Background

I wrote the Impersonator class because of a need to write a web page with ASP.NET to make a server reboot. In order to do this, I needed to impersonate the part of my code that does the actual reboot.

The constructor of the class internally calls the Windows function LogonUser through P/Invoke. Please see the MSDN documentation of the function for a full description of all three parameters (username, domain, password) to the constructor.

Please note: The user context that initiates the impersonation (i.e. not the user context to which it is switched to) needs to have the "Act as part of operating system" privilege set.

Using the code

To use the code, you simply construct the Impersonator class and pass the username, the domain and the password to the constructor. If you place an instance of the class inside a using-block, you need no further steps.

An example project demonstrating the technique is included in the download of this article (please look at the "Program.cs" for the main demonstration source file). Also the complete source code of the class is included inside the source file "Impersonator.cs".

To include the Impersonator class into your project, simply copy and add the source file "Impersonator.cs" to your project, so that it gets compiled with your project.

Conclusion

In this article, I've shown you a small class to quickly and easily impersonate a part of your code to run under another user context. Hopefully you'll find this class useful.

For questions, comments and remarks, please use the commenting section at the bottom of this article.

References

In addition to the links in the article, the following references might be of interest:

Share

About the Author

Uwe does programming since 1989 with experiences in Assembler, C++, MFC and lots of web- and database stuff and now uses ASP.NET and C# extensively, too. He has also teached programming to students at the local university.

In his free time, he does climbing, running and mountain biking. Recently he became a father of a cute boy.

Comments and Discussions

A really nice piece of work. Thanks for sharing. I originally went down the Interop route for the MPR stuff (WNetAddConnectionXX etc) but actually impersonation was what I should have used in the first place. This really saved me a lot of time, so thanks again.

This is quite neat. But lots of people should know that this brings a security risk.
Since decompiling C# Applications isn't that hard. It's way to easy. And lost of people don't know about that.
So if you want to use this, you should KNOW that you have to 'hide' the Passwd of your Admin.

thats right if you are hardcoding password
using it with password from (for example) form works fine
the one important thing is that the account you are using must be acceptable on the machine where app is working
for example domain admin can use it ONLY on machine inside domian