.net 常識 impersonate user 模擬用戶
在.net中 程序運行的時候的權限一般等于運行這個程序的帳號的權限
例如asp.net一般是 network service
console一般是當前用戶
計劃任務中也可以指定用什么帳號運行當前的程序
asp.net中也可以在web.config中指定用什么帳號運行當前程序
本文介紹了如果在你知道用戶名,或者是用戶名和密碼的情況下 使用特定的帳號密碼執行特定的代碼,這樣你在運行時就可以切換當前程序的帳號和權限以完成特定的目標
1.遠程操作不同的機器需要不同的權限 (如果沒有AD的話)
2.將程序切換到其他AD去
3.利用已知的帳號和密碼,在運行時提高權限
實現方式1,只知道帳號不知道密碼,(這種執行方式是受限的,不完全的模擬)
以下代碼修改了線程本身的principal,就是執行線程的代理用戶
private static void SetThreadPrincipal(string loginId)
{
string[] roles = Roles.GetRolesForUser(loginId);
System.Security.Principal.IIdentity userIdentity = new System.Security.Principal.GenericIdentity(loginId);
System.Security.Principal.IPrincipal userPrincipal = new System.Security.Principal.GenericPrincipal(userIdentity, roles);
Thread.CurrentPrincipal = userPrincipal;
}
實現方式2 知道帳號密碼和域(直接用新的帳號密碼登錄執行新的操作)
參考以下代碼....有點長
public static bool ImpersonateValidUser(String userName, String domain, String password)
{
//ServiceContext.SetThreadPrincipal();
WindowsImpersonationContext impersonationContext;
WindowsIdentity tempWindowsIdentity;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
if (RevertToSelf())
{
if (LogonUserA(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();
if (impersonationContext != null)
{
CloseHandle(token);
CloseHandle(tokenDuplicate);
return true;
}
}
}
}
if (token != IntPtr.Zero)
CloseHandle(token);
if (tokenDuplicate != IntPtr.Zero)
CloseHandle(tokenDuplicate);
return false;
}
#region win32 api extend method
[DllImport("advapi32.dll")]
static extern int LogonUserA(String lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern int DuplicateToken(IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
static extern bool CloseHandle(IntPtr handle);
const int LOGON32_LOGON_INTERACTIVE = 2;
const int LOGON32_PROVIDER_DEFAULT = 0;
#endregion
BTW 1:如果想修改整個程序的Principal 一般我們只要調用AppDomain.CurrentDomain.SetPrincipal 就可以了 (大部分.net程序都只有一個域)
BTW 2:另外由于修改了當前的principal,也就是說你換了一個帳號執行當前代碼,一般情況下執行完操作以后要記得換回原來的帳號...(不同帳號對應不同操作的情況)
WindowsIdentity WindowsIdentity_1024 = WindowsIdentity.GetCurrent();
try
{
//......operation
}
finally
{
if(WindowsIdentity_1024!=null)
WindowsIdentity_1024.Impersonate();
}
浙公網安備 33010602011771號