Click here to Skip to main content
Click here to Skip to main content

A small C# Class for impersonating a User

By , 11 Apr 2005
 

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.

(For the latest changes, please see the History section below).

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.

The following is a schematic example of how to use the class:

... 
using ( new Impersonator( "myUsername", "myDomainname", "myPassword" ) )
{
   ...
   
   <code that executes under the new context>
  
   ...
}
  
...

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:

  1. Google search for "Windows Impersonation"

History

  • 2005-04-11: Created first version of article.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Uwe Keim
Chief Technology Officer Zeta Producer Desktop CMS
Germany Germany
Member
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.
 
Some cool, free software from us:
 
Free Test Management Software - Intuitive, competitive, Test Plans. Download now!  
Homepage erstellen - Intuitive, very easy to use. Download now!  
Send large Files online for free by Email
Some random fun stuff in German

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionWindows Server 2012memberRiqiTang13 May '13 - 2:06 
I can't seem to get this to work on Windows Server 2012. I get the following throws an exception:
			
System.Collections.IList errors = null;
try
{
    // Launch PowerShell and execute commands
    using ( new Impersonator ( "Administrator", "Domain", "Password" ) )
    {
    	using ( RunspaceInvoke invoker = new RunspaceInvoke() )
    	{
    		// Launch PowerShell
    		invoker.Invoke("Set-ExecutionPolicy Unrestricted", null, out errors);
                // Other code
        }
    }
}
 
The exception: "Invalid token for impersonation - it cannot be duplicated."
 
Does this mean that the impersonator won't work on Windows Server 2012?
GeneralMy vote of 5member Orcun Iyigun7 Apr '13 - 21:45 
Nice article.
GeneralMy vote of 5memberSebastianN_N3 Apr '13 - 11:26 
Really liked this one! And pietvredeveld solution its also great!
QuestionAD Directory catastrophic failurememberMacUseless12 Dec '12 - 2:52 
Using the class returns a catastrophic failure,
 
I'm using the code as follows,
        private void btnOmzetten_Click(object sender, EventArgs e)
        {
            if(string.IsNullOrWhiteSpace(txtProfiel.Text))
            {           
                MessageBox.Show("Het veld mag niet leeg zijn","Leeg",MessageBoxButtons.OK,MessageBoxIcon.Asterisk);
                txtProfiel.Focus();
                txtLog.Text = "Er is geen profiel ingevult";
            }
            else
            {
                using (new Impersonator(txtGebruiker.Text, txtDomein.Text, txtPw.Text))
                {
                    string profile = GetProfilePath(txtProfiel.Text);
                    txtLog.Text = profile;
                }
}
And the part where i get the catastrophic failure is :
        private string GetProfilePath(string user)
        {
            DirectoryEntry dirEntry = CreateDirEntry(txtGebruiker.Text, txtPw.Text);
            DirectorySearcher dirSearcher = new DirectorySearcher();
            dirSearcher.Filter = "mail=" + user;// er wordt hier gefilterd op email adres
            dirSearcher.PropertiesToLoad.Add("profilePath");// uit AD wordt het profiel pad gelezen en opgeslagen.
            SearchResult sResult = dirSearcher.FindOne();
            
            if (sResult == null)
            {
                MessageBox.Show("Niks gevonden", "Fout", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                txtLog.Text = "Er is niks gevonden";
                return null;
            }
                DirectoryEntry dirEntr = new DirectoryEntry(sResult.Path);
                dirEntr.Username = txtGebruiker.Text;
                dirEntr.Password = txtPw.Text;
                string profile = dirEntr.Properties["profilePath"][0].ToString(); //terug komende nullreference, lokaal geen probleem op server wel
                dirEntr.Close();// this part returns catastrophic failure
                return profile;
        }
 
I'm not sure what i'm doing wrong.
Any help or suggestions are welcome,
GeneralThanks!membersumit ch26 Nov '12 - 21:45 
This is what I was looking for
Questionnot working for SharePoint 2010 codememberabcrahul29 Jun '12 - 3:12 
not working for SharePoint 2010 code
AnswerRe: not working for SharePoint 2010 codememberWayne Dailey13 Sep '12 - 8:01 
Did you ever get it working? Is there a place to get the most current version of the program?
AnswerRe: not working for SharePoint 2010 codesitebuilderUwe Keim13 Sep '12 - 18:10 
"Not working" is usually the worst error description one can think of. Ensures you get no help, guaranteed!
 
If you really want help, try following these rules [^].
Wollen Sie ganz einfach Ihre eigene Homepage erstellen, ohne HTML-Kenntnisse, einfach, professionell und mit viel Freude? Probieren Sie unser Desktop Content Management System (CMS) Zeta Producer für Windows aus. Komplett mit eigenem Shop, Gästebuch, Weblog, Bildergalerien, Integration von YouTube-Videos. Wir haben eine aktive Anwender-Community, schnellen Support, sympathische Support-Mitarbeiter.

SuggestionImproved version without CA warnings and memory leaks [modified]memberpietvredeveld25 Apr '12 - 11:06 
Hi,
The original code has a lot of CA warnings and has some small memory leaks. I've improved the code regarding this issues,without changing the functionality. When interested contact me .
 
edit: Here is the code http://pastebin.com/EmKYDN6R[^]
 
Regards
Piet

modified 26 Apr '12 - 16:04.

GeneralRe: Improved version without CA warnings and memory leakssitebuilderUwe Keim25 Apr '12 - 12:11 
Sure! You could simply link a pastebin.com here for others until I can include it.
Wollen Sie ganz einfach Ihre eigene Homepage erstellen, ohne HTML-Kenntnisse, einfach, professionell und mit viel Freude? Probieren Sie unser Desktop Content Management System (CMS) Zeta Producer für Windows aus. Komplett mit eigenem Shop, Gästebuch, Weblog, Bildergalerien, Integration von YouTube-Videos. Wir haben eine aktive Anwender-Community, schnellen Support, sympathische Support-Mitarbeiter.

GeneralRe: Improved version without CA warnings and memory leaksmemberpietvredeveld26 Apr '12 - 10:01 
Ok, I didn't know how to post the code here...
 
Here is the link to my improvements http://pastebin.com/EmKYDN6R[^]
 
Happy coding,
Piet
QuestionImpersonator and WebRequest doesn´t workmembervicprepr18 Apr '12 - 4:15 
Hi,
 
The code does not work (not impersonate) when I am trying to access a website from a computer located on a different network. Any suggestions?
 
Thanks in advance.
QuestionNicememberopik taufik29 Mar '12 - 18:06 
Very Nice Indeed Smile | :)
QuestionWorks as expected with ASP.NET MVC3 and .Net 4 in Windows 7memberReve1018 Mar '12 - 7:19 
Thank you very much. I like the concise and clean code.
QuestionbravomemberMember 863703210 Feb '12 - 5:51 
very very good job and nice and easy to use it
 

bravo from french programmer
GeneralMy vote of 5memberKris Clayton27 Jan '12 - 0:19 
This has solved problems for me multiple times Smile | :)
QuestionNot Working in Win Sever 2008 R2memberanilkuchi1 Nov '11 - 11:39 
Hi when i am using the same code in Windows Server 2008 R2 it is giving me
 
Logon failure: the user has not been granted the requested logon type at this computer
 
where as it is working in windows XP ,am i missing something ,please let me know
 
Thanks
 
Naga Aditya
AnswerRe: Not Working in Win Sever 2008 R2memberchardog3 Dec '11 - 12:51 
try changing "LOGON32_LOGON_INTERACTIVE" value to 9
GeneralVery Nice & EasymemberSrikanth. Vemulapalli16 Oct '11 - 19:43 
Hi,
 
The code was very helpful. The way it was writen also good.
 
Thanks,
Sri. Smile | :)
Srikanth.Vemulapally

QuestionMy Votememberahmed farag Ibrahim8 Oct '11 - 1:43 
Very Helpful Code , my vote is 5
 
Thanks
Ahmed Farag
AnswerRe: My VotesitebuilderUwe Keim8 Oct '11 - 21:40 
Thank you, Ahmed!
Wollen Sie ganz einfach Ihre eigene Homepage erstellen, ohne HTML-Kenntnisse, einfach, professionell und mit viel Freude? Probieren Sie unser Desktop Content Management System (CMS) Zeta Producer für Windows aus. Komplett mit eigenem Shop, Gästebuch, Weblog, Bildergalerien, Integration von YouTube-Videos. Wir haben eine aktive Anwender-Community, schnellen Support, sympathische Support-Mitarbeiter.

GeneralMy vote of 5memberbscaer7 Oct '11 - 10:11 
Very well-written code
QuestionCall LogonUsermemberMember 822764117 Sep '11 - 13:38 
How can i call LogonUser with a username "something" and without any password?
QuestionImpersonating to grant writing files privilege ?memberPatrice Dargenton14 Sep '11 - 3:58 
Hello, in your demo project you show how to list system files : is it possible to grant writing files privilege ? I don't know why I can't do this using your code. Any idea ? (I read all the comments in this forum)
Thank you.
Patrice.
AnswerRe: Impersonating to grant writing files privilege ?memberPatrice Dargenton18 Sep '11 - 21:52 
Ok, I found the problem : we must use LOGON_TYPE = LOGON32_LOGON_INTERACTIVE (and not LOGON32_LOGON_NEW_CREDENTIALS)
Note : 'Act as part of operating system' privilege set : only for Windows 2000 users (see MSDN paper)
Now it works both on Vista and XP.
Patrice.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 11 Apr 2005
Article Copyright 2005 by Uwe Keim
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid