实质上是通过WindowsIdentity.Impersonate()的方法,其中需要调用Win API来获得活用的Handle,用法其实很简单,因为在自己的代码中需要用到,就稍微封装了一下:
?public class IdentityImpersonation {
??[DllImport("advapi32.dll", SetLastError=true)]
??public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
???int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
??[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
??public extern static bool DuplicateToken(IntPtr ExistingTokenHandle,
???int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);
??[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
??public extern static bool CloseHandle(IntPtr handle);
??// 要模拟的用户的用户名、密码、域(机器名)
??private String _sImperUsername;
??private String _sImperPassword;
??private String _sImperDomain;
??// 记录模拟上下文
??private WindowsImpersonationContext _imperContext;
??private IntPtr _adminToken;
??private IntPtr _dupeToken;
??// 是否已停止模拟
??private Boolean _bClosed;
??public IdentityImpersonation(String impersonationUsername, String impersonationPassword, String impersonationDomain) {
???_sImperUsername = impersonationUsername;
???_sImperPassword = impersonationPassword;
???_sImperDomain = impersonationDomain;
???_adminToken = IntPtr.Zero;
???_dupeToken = IntPtr.Zero;
???_bClosed = true;
??}
??~IdentityImpersonation() {
???if(! _bClosed) {
????StopImpersonation();
???}
??}
??public Boolean BeginImpersonate() {
?
???Boolean bLogined = LogonUser(_sImperUsername, _sImperDomain, _sImperPassword, 2, 0, ref _adminToken);
???
???if(! bLogined) {
????return false;
???}
???Boolean bDuped = DuplicateToken(_adminToken, 2, ref _dupeToken);
???if(! bDuped) {
????return false;
???}
???WindowsIdentity fakeId = new WindowsIdentity(_dupeToken);
???_imperContext = fakeId.Impersonate();
???_bClosed = false;
???return true;
??}
??public void StopImpersonate() {
???_imperContext.Undo();
???CloseHandle(_dupeToken);
???CloseHandle(_adminToken);
???_bClosed = true;
??}
?}
?
使用示例:
IdentityImpersonation imper = new IdentityImpersonation("tsg", "123456", "webreal");
imper.BeginImpersonation();
// ...
imper.StopImpersonation();