LogonUser和委托

我正在使用LogonUser win32 api:

token = LogonUser(...) WindowsIdentity newId = new WindowsIdentity(token); WindowsImpersonationContext impersonatedUser = newId.Impersonate(); 

但是,在此之后调用WCF服务时,我无法使用模拟身份。 我认为这是因为impersonatedUser.ImpersonationLevel等于模拟。

这是什么原因? 是ImpersonationLevel.Identification的级别我需要什么? 如何获得这样的水平?

我不知道这是否适用于WCF。 但我们在生产Web应用程序中使用它来模拟读取和写入文件系统的文件。 您需要为AdvApi32.LogonUser,AdvApi32.DuplicateToken和Kernel32.CloseHandle定义API,并确保在完成后关闭WindowsImpersonationContext。

  /// impersonates a user /// domain\name of the user account /// the user's password /// the new WindowsImpersonationContext public static WindowsImpersonationContext ImpersonateUser(String username, String password) { WindowsIdentity winId = WindowsIdentity.GetCurrent(); if (winId != null) { if (string.Compare(winId.Name, username, true) == 0) { return null; } } //define the handles IntPtr existingTokenHandle = IntPtr.Zero; IntPtr duplicateTokenHandle = IntPtr.Zero; String domain; if (username.IndexOf("\\") > 0) { //split domain and name String[] splitUserName = username.Split('\\'); domain = splitUserName[0]; username = splitUserName[1]; } else { domain = String.Empty; } try { //get a security token bool isOkay = AdvApi32.LogonUser(username, domain, password, (int) AdvApi32.LogonTypes.LOGON32_LOGON_INTERACTIVE, (int) AdvApi32.LogonTypes.LOGON32_PROVIDER_DEFAULT, ref existingTokenHandle); if (!isOkay) { int lastWin32Error = Marshal.GetLastWin32Error(); int lastError = Kernel32.GetLastError(); throw new Exception("LogonUser Failed: " + lastWin32Error + " - " + lastError); } // copy the token isOkay = AdvApi32.DuplicateToken(existingTokenHandle, (int) AdvApi32.SecurityImpersonationLevel.SecurityImpersonation, ref duplicateTokenHandle); if (!isOkay) { int lastWin32Error = Marshal.GetLastWin32Error(); int lastError = Kernel32.GetLastError(); Kernel32.CloseHandle(existingTokenHandle); throw new Exception("DuplicateToken Failed: " + lastWin32Error + " - " + lastError); } // create an identity from the token WindowsIdentity newId = new WindowsIdentity(duplicateTokenHandle); WindowsImpersonationContext impersonatedUser = newId.Impersonate(); return impersonatedUser; } finally { //free all handles if (existingTokenHandle != IntPtr.Zero) { Kernel32.CloseHandle(existingTokenHandle); } if (duplicateTokenHandle != IntPtr.Zero) { Kernel32.CloseHandle(duplicateTokenHandle); } } } 

在此之后,我无法使用模拟身份

模拟应该对在同一个盒子上访问有效,但不能在网络上访问。

正如consultutah的代码所示,它可能需要调用DuplicateToken()以便在使用之前将登录令牌转换为模拟令牌。

我认为这是因为impersonatedUser.ImpersonationLevel等于模拟。

如果您需要充当其他系统的模拟用户,则需要更高级别的模拟,称为“委派”。 这基本上相当于拥有用户的密码,因此您可以将自己表示为他人。