//Sample 1: WindowsImpersonationContext.cs using System.Security.Principal; using System.Security.Permissions; [ assembly: SecurityPermissionAttribute ( SecurityAction.RequestMinimum, UnmanagedCode=true ) ] [ assembly: PermissionSetAttribute ( SecurityAction.RequestMinimum, Name = "FullTrust" ) ] namespace Microshaoft { // This sample demonstrates the use of the WindowsIdentity class to impersonate a user. // IMPORTANT NOTES: // This sample can be run only on Windows XP. The default Windows 2000 security policy // prevents this sample from executing properly, and changing the policy to allow // proper execution presents a security risk. // This sample requests the user to enter a password on the console screen. // Because the console window does not support methods allowing the password to be masked, // it will be visible to anyone viewing the screen. // The sample is intended to be executed in a .NET Framework 1.1 environment. To execute // this code in a 1.0 environment you will need to use a duplicate token in the call to the // WindowsIdentity constructor. See KB article Q319615 for more information. using System; using System.Runtime.InteropServices; using Microshaoft; public class ImpersonationDemo { [ 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 ) ] private static extern int FormatMessage ( int dwFlags, ref IntPtr lpSource, int dwMessageId, int dwLanguageId, ref string lpBuffer, int nSize, IntPtr args ); [ DllImport ( "kernel32.dll", CharSet = CharSet.Auto ) ] public extern static bool CloseHandle(IntPtr handle); [ DllImport ( "advapi32.dll", CharSet = CharSet.Auto, SetLastError = true ) ] public extern static bool DuplicateToken ( IntPtr ExistingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle ); // Test harness. // If you incorporate this code into a DLL, be sure to demand FullTrust. [ PermissionSetAttribute ( SecurityAction.Demand, Name = "FullTrust" ) ] public static void Main(string[] args) { IntPtr tokenHandle = new IntPtr(0); IntPtr dupeTokenHandle = new IntPtr(0); try { string userName, domainName; // Get the user token for the specified user, domain, and password using the // unmanaged LogonUser method. // The local machine name can be used for the domain name to impersonate a user on this machine. Console.WriteLine("Enter the name of the domain on which to log on: "); domainName = Console.ReadLine(); Console.WriteLine("Enter the login of a user on {0} that you wish to impersonate: ", domainName); userName = Console.ReadLine(); Console.WriteLine("Enter the password for {0}: ", userName); const int LOGON32_PROVIDER_DEFAULT = 0; //This parameter causes LogonUser to create a primary token. const int LOGON32_LOGON_INTERACTIVE = 2; tokenHandle = IntPtr.Zero; string password; password = ConsoleHelper.ReadMaskLine('*', true); // Call LogonUser to obtain a handle to an access token. bool returnValue = LogonUser ( userName, domainName, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref tokenHandle ); Console.WriteLine("LogonUser called."); if (false == returnValue) { int ret = Marshal.GetLastWin32Error(); Console.WriteLine("LogonUser failed with error code : {0}", ret); throw new System.ComponentModel.Win32Exception(ret); } Console.WriteLine("Did LogonUser Succeed? " + (returnValue? "Yes" : "No")); Console.WriteLine("Value of Windows NT token: " + tokenHandle); // Check the identity. Console.WriteLine("Before impersonation: " + WindowsIdentity.GetCurrent().Name); // Use the token handle returned by LogonUser. WindowsIdentity newId = new WindowsIdentity(tokenHandle); WindowsImpersonationContext impersonatedUser = newId.Impersonate(); // Check the identity. Console.WriteLine("After impersonation: " + WindowsIdentity.GetCurrent().Name); // Stop impersonating the user. impersonatedUser.Undo(); // Check the identity. Console.WriteLine("After Undo: " + WindowsIdentity.GetCurrent().Name); // Free the tokens. if (tokenHandle != IntPtr.Zero) { CloseHandle(tokenHandle); } } catch(Exception ex) { Console.WriteLine("Exception occurred. " + ex.Message); } } } } namespace Microshaoft { using System; public class ConsoleHelper { public static string ReadMaskLine ( char PasswordChar , bool WithMask ) { string password = ""; ConsoleKey ck; string s = @"~!@#$%&*()_+`1234567890-="; //可输入字符 s += @"QWERTYUIOP{}|qwertyuiop[]\"; s += "ASDFGHJKL:\"asdfghjkl;'"; s += "ZXCVBNM<>?zxcvbnm,./ "; do { ConsoleKeyInfo cki = Console.ReadKey(true); char c = cki.KeyChar; ck = cki.Key; int p = Console.CursorLeft; if (ck == ConsoleKey.Backspace) { string left = ""; if (p > 0) { left = password.Substring(0, p - 1); } string right = password.Substring(p); password = left + right; Console.Write(c); string output = right; if (WithMask) { output = GetPasswordChars(right, PasswordChar); } output += "\0"; Console.Write(output); if (p > 0) { p --; } } else if (ck == ConsoleKey.Delete) { string left = ""; if (p > 0) { left = password.Substring(0, p); } string right = ""; if (p < password.Length) { right = password.Substring(p + 1); } password = left + right; //Console.Write(right + " "); string output = right; if (WithMask) { output = GetPasswordChars(right, PasswordChar); } output += "\0"; Console.Write(output); } else { if (s.IndexOf(c) >= 0) { string left = password.Substring(0, p); string right = password.Substring(p); password = left + c + right; string output = c + right; if (WithMask) { output = GetPasswordChars(c + right, PasswordChar); } Console.Write(output); p ++; } else { switch (ck) { case ConsoleKey.LeftArrow : if (p > 0) { p --; } break; case ConsoleKey.RightArrow : if (p < password.Length) { p ++; } break; case ConsoleKey.Home : p = 0; break; case ConsoleKey.End : p = password.Length; break; default : Console.Beep(); break; } } } Console.CursorLeft = p; } while (ck != ConsoleKey.Enter); //Console.WriteLine("[" + password + "]"); return password; } private static string GetPasswordChars(string s, char c) { string passwordChars = ""; for (int i = 0; i < s.Length; i++) { passwordChars += c; } return passwordChars; } } } //Sample2.cs namespace TestApplication { using System; using System.Security.Principal; using Microshaoft.Win32; using Microshaoft; public class Class1 { /// <summary> /// 应用程序的主入口点。 /// </summary> //[STAThread] static void Main(string[] args) { Console.WriteLine(WindowsIdentity.GetCurrent().Name); Console.WriteLine("pls input your username:"); string user; user = Console.ReadLine(); Console.WriteLine("pls input your password:"); string password; password = ConsoleHelper.ReadMaskLine('*', true); Console.WriteLine(); Console.WriteLine("pls input your domain:"); string domain; domain = Console.ReadLine(); LogonImpersonate x = new LogonImpersonate ( user , password , domain ); Console.WriteLine("Hello {0}", WindowsIdentity.GetCurrent().Name); } } } namespace Microshaoft { using System; public class ConsoleHelper { public static string ReadMaskLine ( char PasswordChar , bool WithMask ) { string password = ""; ConsoleKey ck; string s = @"~!@#$%&*()_+`1234567890-="; //可输入字符 s += @"QWERTYUIOP{}|qwertyuiop[]\"; s += "ASDFGHJKL:\"asdfghjkl;'"; s += "ZXCVBNM<>?zxcvbnm,./ "; do { ConsoleKeyInfo cki = Console.ReadKey(true); char c = cki.KeyChar; ck = cki.Key; int p = Console.CursorLeft; if (ck == ConsoleKey.Backspace) { string left = ""; if (p > 0) { left = password.Substring(0, p - 1); } string right = password.Substring(p); password = left + right; Console.Write(c); string output = right; if (WithMask) { output = GetPasswordChars(right, PasswordChar); } output += "\0"; Console.Write(output); if (p > 0) { p --; } } else if (ck == ConsoleKey.Delete) { string left = ""; if (p > 0) { left = password.Substring(0, p); } string right = ""; if (p < password.Length) { right = password.Substring(p + 1); } password = left + right; //Console.Write(right + " "); string output = right; if (WithMask) { output = GetPasswordChars(right, PasswordChar); } output += "\0"; Console.Write(output); } else { if (s.IndexOf(c) >= 0) { string left = password.Substring(0, p); string right = password.Substring(p); password = left + c + right; string output = c + right; if (WithMask) { output = GetPasswordChars(c + right, PasswordChar); } Console.Write(output); p ++; } else { switch (ck) { case ConsoleKey.LeftArrow : if (p > 0) { p --; } break; case ConsoleKey.RightArrow : if (p < password.Length) { p ++; } break; case ConsoleKey.Home : p = 0; break; case ConsoleKey.End : p = password.Length; break; default : Console.Beep(); break; } } } Console.CursorLeft = p; } while (ck != ConsoleKey.Enter); //Console.WriteLine("[" + password + "]"); return password; } private static string GetPasswordChars(string s, char c) { string passwordChars = ""; for (int i = 0; i < s.Length; i++) { passwordChars += c; } return passwordChars; } } } namespace Microshaoft.Win32 { using System; using System.Runtime.InteropServices; using System.Security.Principal; public class LogonImpersonate : IDisposable { static public string DefaultDomain { get { return "."; } } #region DynamicInvoke static public object DynamicInvoke ( string username , string password , Delegate handler , object[] args ) { if(handler == null) { throw(new ArgumentNullException("handler")); } using(new LogonImpersonate(username,password)) { return handler.DynamicInvoke(args); } } static public object DynamicInvoke ( string username , string password , string domain , Delegate handler , object[] args ) { if(handler == null) { throw(new ArgumentNullException("handler")); } using(new LogonImpersonate(username,password,domain)) { return handler.DynamicInvoke(args); } } static public void DynamicInvoke(string username,string password,EventHandler handler,object sender,EventArgs e) { if(handler == null) { throw(new ArgumentNullException("handler")); } using(new LogonImpersonate(username,password)) { handler(sender,e); } } static public void DynamicInvoke ( string username , string password , string domain , EventHandler handler , object sender , EventArgs e ) { if(handler == null) { throw(new ArgumentNullException("handler")); } using(new LogonImpersonate(username,password,domain)) { handler(sender, e); } } #endregion #region PInvoke const int LOGON32_LOGON_INTERACTIVE=2; const int LOGON32_PROVIDER_DEFAULT=0; [DllImport("Kernel32.dll")] extern static int FormatMessage ( int flag , ref IntPtr source , int msgid , int langid , ref string buf ,int size , ref IntPtr args ); [DllImport("Kernel32.dll")] extern static bool CloseHandle(IntPtr handle); [DllImport("Advapi32.dll",SetLastError=true)] extern static bool LogonUser ( string lpszUsername , string lpszDomain , string lpszPassword , int dwLogonType , int dwLogonProvider , ref IntPtr phToken ); #endregion IntPtr token; WindowsImpersonationContext context; public LogonImpersonate(string username,string password) { if(username == null) { throw(new ArgumentNullException("username")); } if (password == null) { throw(new ArgumentNullException("password")); } if(username.IndexOf("\\") == -1) { Init(username, password, DefaultDomain); } else { string[] pair = username.Split(new char[]{'\\'},2); Init(pair[1],password,pair[0]); } } public LogonImpersonate(string username,string password,string domain) { if (username == null) throw (new ArgumentNullException("username")); if (password == null) throw (new ArgumentNullException("password")); if (domain == null) throw(new ArgumentNullException("domain")); Init(username, password, domain); } void Init ( string username , string password , string domain ) { if ( LogonUser ( username , domain , password , LOGON32_LOGON_INTERACTIVE , LOGON32_PROVIDER_DEFAULT , ref token ) ) { bool error=true; try { context = WindowsIdentity.Impersonate(token); error = false; } finally { if(error) { CloseHandle(token); } } } else { int err = Marshal.GetLastWin32Error(); IntPtr tempptr = IntPtr.Zero; string msg = null; FormatMessage ( 0x1300 , ref tempptr , err , 0 , ref msg , 255 , ref tempptr ); throw(new Exception(msg)); } } ~LogonImpersonate() { Dispose(); } public void Dispose() { if (context != null) { try { context.Undo(); } finally { CloseHandle(token); context=null; } } } } }