//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;
}
}
}
}
}