I'm having problems trying to impersonate an active directory user in a desktop application. Every time I use the LogOn API the result is false.
The user and domain do exist since I can also authenticate the user over the DirectoryServices.AccountManagement
on the same application.
Have read the documentation about impersonation in the Microsoft site and even some post here on the stack. Also, have used the SimpleImpersonation
library with the same results.
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,
}
}
I don't know if the reason it isn't working is that my computer is running on an outside network and connecting/authenticating to the company network over a VPN.
Edit 1. The resulting error code is 1326 (unknown user name or bad password)
Edit 2. The method is trying to obtain the identity token for later use on thread impersonation.