Impersonate Class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace ImpersonateTestApp | |
{ | |
public class Impersonator : | |
IDisposable | |
{ | |
#region Public methods. | |
public Impersonator( | |
string userName, | |
string domainName, | |
string password) | |
{ | |
ImpersonateValidUser(userName, domainName, password); | |
} | |
// ----------------------------------------------------------------- | |
#endregion | |
#region IDisposable member. | |
// --------------------------------------------------------- | |
public void Dispose() | |
{ | |
UndoImpersonation(); | |
} | |
// ----------------------------------------------------------------- | |
#endregion | |
#region P/Invoke. | |
// --------------------------------------------------------- | |
[DllImport("advapi32.dll", SetLastError = true)] | |
private static extern int LogonUser( | |
string lpszUserName, | |
string lpszDomain, | |
string lpszPassword, | |
int dwLogonType, | |
int dwLogonProvider, | |
ref IntPtr phToken); | |
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] | |
private static extern int DuplicateToken( | |
IntPtr hToken, | |
int impersonationLevel, | |
ref IntPtr hNewToken); | |
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] | |
private static extern bool RevertToSelf(); | |
[DllImport("kernel32.dll", CharSet = CharSet.Auto)] | |
private static extern bool CloseHandle( | |
IntPtr handle); | |
private const int LOGON32_LOGON_INTERACTIVE = 2; | |
private const int LOGON32_PROVIDER_DEFAULT = 0; | |
// ----------------------------------------------------------------- | |
#endregion | |
#region Private member. | |
// --------------------------------------------------------- | |
private void ImpersonateValidUser( | |
string userName, | |
string domain, | |
string password) | |
{ | |
WindowsIdentity tempWindowsIdentity = null; | |
IntPtr token = IntPtr.Zero; | |
IntPtr tokenDuplicate = IntPtr.Zero; | |
try | |
{ | |
if (RevertToSelf()) | |
{ | |
if (LogonUser( | |
userName, | |
domain, | |
password, | |
LOGON32_LOGON_INTERACTIVE, | |
LOGON32_PROVIDER_DEFAULT, | |
ref token) != 0) | |
{ | |
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0) | |
{ | |
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate); | |
impersonationContext = tempWindowsIdentity.Impersonate(); | |
} | |
else | |
{ | |
throw new Win32Exception(Marshal.GetLastWin32Error()); | |
} | |
} | |
else | |
{ | |
throw new Win32Exception(Marshal.GetLastWin32Error()); | |
} | |
} | |
else | |
{ | |
throw new Win32Exception(Marshal.GetLastWin32Error()); | |
} | |
} | |
finally | |
{ | |
if (token != IntPtr.Zero) | |
{ | |
CloseHandle(token); | |
} | |
if (tokenDuplicate != IntPtr.Zero) | |
{ | |
CloseHandle(tokenDuplicate); | |
} | |
} | |
} | |
/// <summary> | |
/// Reverts the impersonation. | |
/// </summary> | |
private void UndoImpersonation() | |
{ | |
if (impersonationContext != null) | |
{ | |
impersonationContext.Undo(); | |
} | |
} | |
private WindowsImpersonationContext impersonationContext = null; | |
// ----------------------------------------------------------------- | |
#endregion | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment