用指定账号运行代码

需要调用Windows登陆函数,从AdvAPI32.dll里面导入3个函数LogonUser,DuplicateToken和CloseHandle。具体过程和代码一并写在下面:

从Dll导入3个Windows函数
  1. [DllImport("advapi32.dll", SetLastError = true)]
  2. private static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);
  3. [DllImport("advapi32.dll", SetLastError = true)]
  4. private static extern bool DuplicateToken(IntPtr ExistingTokenHandle, Int32 ImpersonationLevel, out IntPtr DuplicateTokenHandle);
  5. [DllImport("advapi32.dll", SetLastError = true)]
  6. private static extern bool CloseHandle(IntPtr hHandle);

定义一些枚举变量

定义Windows函数所需的枚举变量
  1. public enum WindowsLogonType
  2. {
  3.     INTERACTIVE = 2,
  4.     NETWORK = 3,
  5.     BATCH = 4,
  6.     SERVICE = 5,
  7.     UNLOCK = 7,
  8.     NETWORK_CLEARTEXT = 8,
  9.     NEW_CREDENTIALS = 9
  10. }
  11.  
  12. public enum ImpersonationLevel
  13. {
  14.     SecurityAnonymous,
  15.     SecurityIdentification,
  16.     SecurityImpersonation,
  17.     SecurityDelegation
  18. }
  19.  
  20. const Int32 LOGON32_PROVIDER_DEFAULT = 0;


开始登陆过程:

登陆过程代码
  1. IntPtr hToken = IntPtr.Zero;
  2. WindowsIdentity windowsIdentity;
  3.  
  4. if (LogonUser(username, domain, password, LOGON32_LOGON_SERVICE, LOGON32_PROVIDER_DEFAULT, out hToken))
  5. {
  6.     windowsIdentity = new WindowsIdentity(hToken);
  7.     WindowsImpersonationContext impersonationContext = windowsIdentity.Impersonate();
  8.     //Code here running with new credential
  9.     impersonationContext.Undo();
  10.     //exit new credential context, old credential become active.
  11. }
  12. else
  13. {
  14.     int ret = Marshal.GetLastWin32Error();
  15.     Console.WriteLine("Logon as service failed, Error Code: " + ret.ToString());
  16. }
  17. if (hToken != IntPtr.Zero) CloseHandle(hToken);

Windows登陆后返回一个句柄,拿着这个句柄可以生成一个WindowsIdentity,然后WindowsIdentity的Impersonate函数会把当前账号入栈,新帐号激活,并且返回一个WindowsImpersonationContext。这时后面的代码就运行在新帐号权限下面,想返回之前的账号时用WindowsImpersonationContext的Undo函数就可以撤销账号的更改,旧帐号激活。

posted @ 2011-03-08 14:22  Haitao Chen  阅读(634)  评论(0编辑  收藏  举报