我在尝试在桌面应用程序中模拟活动目录用户时遇到了问题。每次使用LogOn API时,结果都为false。
该用户和域确实存在,因为我也可以在同一应用程序上通过DirectoryServices.AccountManagement
对用户进行身份验证。
已阅读Microsoft网站上有关模拟的文档,甚至在此堆栈上发布了一些帖子。此外,还使用了SimpleImpersonation
库,但结果相同。
public class Demo
{
private WindowsImpersonationContext impersonationContext = null;
[DllImport("advapi32.dll", SetLastError = true)]
private static extern int LogonUser(string lpszUserName, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken);
private void Enter()
{
try
{
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
string userName = "myValidUser";
string domain = "my.domain.example";
string password = "myValidPassword";
if (LogonUser(userName, domain, password, (int)LogonType.LOGON32_LOGON_INTERACTIVE, (int)LogonProvider.LOGON32_PROVIDER_WINNT35, ref token) != 0)
{
WindowsIdentity WindowsIdentityPrincipal = new WindowsIdentity(token);
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
WindowsIdentity tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
impersonationContext = tempWindowsIdentity.Impersonate();
}
else
{
throw new Win32Exception(new Win32Exception(Marshal.GetLastWin32Error()).Message);
}
}
else
{
//throws username or pass incorrect
throw new Win32Exception(new Win32Exception(Marshal.GetLastWin32Error()).Message);
}
}
catch (Exception exc)
{
throw exc;
}
}
public enum LogonProvider
{
LOGON32_PROVIDER_DEFAULT = 0,
LOGON32_PROVIDER_WINNT35 = 1,
LOGON32_PROVIDER_WINNT40 = 2,
LOGON32_PROVIDER_WINNT50 = 3
}
private enum LogonType
{
LOGON32_LOGON_INTERACTIVE = 2,
LOGON32_LOGON_NETWORK = 3,
LOGON32_LOGON_BATCH = 4,
LOGON32_LOGON_SERVICE = 5,
LOGON32_LOGON_UNLOCK = 7,
LOGON32_LOGON_NETWORK_CLEARTEXT = 8,
LOGON32_LOGON_NEW_CREDENTIALS = 9,
}
}
我不确定它无法工作的原因是我的计算机正在外部网络上运行,并通过VPN连接/认证到公司网络。
编辑1: 生成的错误代码是1326(未知用户名或密码错误)
编辑2: 此方法尝试获取身份令牌以供后续在线程模拟中使用。