WindowsIdentity Impersonation using C# Code
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Principal;
using System.Runtime.InteropServices;
using System.Security.Permissions;
namespace Test
{
public class ImpersonateUser
{
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool LogonUser(
String lpszUsername,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
private static IntPtr tokenHandle = new IntPtr(0);
private static WindowsImpersonationContext impersonatedUser;
// If you incorporate this code into a DLL, be sure to demand that it
// runs with FullTrust.
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
public void Impersonate(string domainName, string userName, string password)
{
//try
{
// Use the unmanaged LogonUser function to get the user token for
// the specified user, domain, and password.
const int LOGON32_PROVIDER_DEFAULT = 0;
// Passing this parameter causes LogonUser to create a primary token.
const int LOGON32_LOGON_INTERACTIVE = 2;
tokenHandle = IntPtr.Zero;
// ---- Step - 1
// Call LogonUser to obtain a handle to an access token.
bool returnValue = LogonUser(
userName,
domainName,
password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
ref tokenHandle); // tokenHandle - new security token
if (false == returnValue)
{
int ret = Marshal.GetLastWin32Error();
throw new System.ComponentModel.Win32Exception(ret);
}
// ---- Step - 2
WindowsIdentity newId = new WindowsIdentity(tokenHandle);
// ---- Step - 3
impersonatedUser = newId.Impersonate();
}
}
// Stops impersonation
public void Undo()
{
impersonatedUser.Undo();
// Free the tokens.
if (tokenHandle != IntPtr.Zero)
CloseHandle(tokenHandle);
}
}
}
how to use it
ImpersonateUser iu = new ImpersonateUser();
iu.Impersonate("domain", "userName", "password");
//your code
iu.Undo();
Comments
Anonymous
February 03, 2009
works! though how can I accomplish same thing via web.config on IIS7? ThanksAnonymous
February 11, 2009
A very useful addition to my class library! Thank you!Anonymous
March 15, 2009
FileStream data type is a very important feature of SQL Server 2008 and gradually getting popular amongstAnonymous
April 19, 2009
When program was performing,The error is shown: Logon failure: unknown user name or bad password. please help meAnonymous
June 02, 2009
In answer to Mettlus: web.config <configuration> <system.web> <identity impersonate="true" userName="DOMAINUSERNAME" password="PASSWORD" /> </system.web> </configuration> However, it may not be wise to let every session have impersonation.Anonymous
June 29, 2009
I've been looking for some time for code that will allow me to perform an identity impersonate within a HttpModule and this code did exactly what I needed. Thanks.Anonymous
June 29, 2009
Please giuide me the domain name is the Server Machine name or Remote Machine name?Anonymous
September 30, 2009
I rarely post in these things but I just wanted to let you know I really liked this code - and it did exactly what I needed.Anonymous
October 28, 2009
Great Code; Works Perfectly. Thank you for thatAnonymous
November 03, 2009
Excellent code, helped me a lotAnonymous
January 13, 2010
The comment has been removedAnonymous
March 04, 2010
If you want to use it in a using block, use this code instead: public class ImpersonatedUser : IDisposable { private string _domain = ""; private string _username = ""; private string _password = ""; public ImpersonatedUser(string Domain, string Username, string Password) { _domain = Domain; _username = Username; _password = Password; Impersonate(); } [DllImport("advapi32.dll", SetLastError = true)] public static extern bool LogonUser(string User, string Domain, string Password, int LogonType, int LogonProvider, ref IntPtr Token); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] public extern static bool CloseHandle(IntPtr handle); private static IntPtr tokenHandle = new IntPtr(0); private static WindowsImpersonationContext impersonatedUser; // If you incorporate this code into a DLL, be sure to demand that it // runs with FullTrust. /// <summary> /// Impersonates another Windows user /// </summary> /// <param name="Domain">The domain of the user to impersonate</param> /// <param name="Username">The username of the user to impersonate</param> /// <param name="Password">The password of the user to impersonate</param> [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")] private void Impersonate() { //try { // Use the unmanaged LogonUser function to get the user token for // the specified user, domain, and password. const int defaultProvider = 0; // Passing this parameter causes LogonUser to create a primary token. const int interactive = 2; tokenHandle = IntPtr.Zero; // ---- Step - 1 // Call LogonUser to obtain a handle to an access token. bool returnValue = LogonUser(_username, _domain, _password, interactive, defaultProvider, ref tokenHandle); if (false == returnValue) { int ret = Marshal.GetLastWin32Error(); throw new System.ComponentModel.Win32Exception(ret); } // ---- Step - 2 WindowsIdentity newId = new WindowsIdentity(tokenHandle); // ---- Step - 3 impersonatedUser = newId.Impersonate(); } } // Stops impersonation public void Undo() { impersonatedUser.Undo(); // Free the tokens. if (tokenHandle != IntPtr.Zero) CloseHandle(tokenHandle); } #region IDisposable Members public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool Disposing) { if (Disposing) { _domain = null; _username = null; _password = null; } if (impersonatedUser != null) Undo(); impersonatedUser = null; } ~ImpersonatedUser() { Dispose(false); } #endregion } Then you can say: using (new ImpersonatedUser(domain, username, password)) { // You are the impersonated user inside here }Anonymous
June 01, 2010
sdsdsAnonymous
August 15, 2010
Yes perfect! Just what I was looking for! ThanksAnonymous
August 15, 2010
Yes perfect! Just what I was looking for! ThanksAnonymous
September 12, 2010
thanx lott... After 2 days my problem is solved... thank you. perfect Code.Anonymous
October 12, 2011
Exactly what I need, but LogonUser returns false every time, I'm sure the credentials are correct...Anonymous
October 13, 2011
Thank you, Sir! Thank you, thank you, thank you!!Anonymous
February 02, 2012
The comment has been removedAnonymous
July 22, 2012
Hi. Regarding: private static IntPtr tokenHandle = new IntPtr(0); private static WindowsImpersonationContext impersonatedUser; Those two fields are declared static. I'd like to know (if anyone's still checking this blog):-
- Are there any benefits in declaring those variables as static ?
- Are there any consequences (ie: danger) by having those two as static ? I'm talking about using this in ASP.NET environment. Cheers.
- Anonymous
May 22, 2015
have a requirement, where I need to impersonate a logon user using the database account (the database account has access to system tables). I don't want to expose the password, by providing in a web.config file. is there a way to impersonate the logon user using database account without providing the password.