I am trying to test an ASP.NET MVC4 web application connecting to other users at the same time using impersonation. Thus, the idea of ββthe test was to run multiple instances of the driver, each of which has a different outstanding user. It sounds conceptually easy ...
However, if after calling LogonUser with another user from the current one, you start IEDriverServer, when it starts, the application crash dialog box is displayed. This is the information registered in EventLog:
Faulting application name: IEDriverServer.exe, version: 2.44.0.0, time stamp: 0x54496690 Faulting module name: IED7543.tmp, version: 0.0.0.0, time stamp: 0x5449668c Exception code: 0xc0000005 Fault offset: 0x000000000009d609 Faulting process id: 0x760 Faulting application start time: 0x01d00e3d12f93475 Faulting application path: ...\bin\IEDriverServer.exe Faulting module path: C:\Users\user\AppData\Local\Temp\IED7543.tmp Report Id: 5383a54d-7a30-11e4-b39c-000c29b46927
Here is the code I use to impersonate. It is based on all the examples that I found, so I'm not surprised ... We also tried using SimpleImpersonation packege with the same result:
public class ImpersonationHelper { public enum LogonType { Interactive = 2, Network = 3, Batch = 4, Service = 5, Unlock = 7, Cleartext = 8, // Win2K or higher NewCredentials = 9 // Win2K or higher }; public enum LogonProvider { Default = 0, Winnt35 = 1, Winnt40 = 2, Winnt50 = 3 }; public enum ImpersonationLevel { SecurityAnonymous = 0, SecurityIdentification = 1, SecurityImpersonation = 2, SecurityDelegation = 3 } [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken); [DllImport("kernel32.dll")] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] [SuppressUnmanagedCodeSecurity] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool CloseHandle(IntPtr handle); [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken); public sealed class Impersonator : IDisposable { public string Domain { get; private set; } public string User { get; private set; } public string Password { get; private set; } public LogonType Type { get; private set; } public LogonProvider Provider { get; private set; } private WindowsImpersonationContext _context; private IntPtr _token; [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")] public Impersonator(string domain, string user, string password, LogonType type = LogonType.Interactive, LogonProvider provider = LogonProvider.Default) { Domain = domain; User = user; Password = password; Type = type; Provider = provider; _token = IntPtr.Zero; Logon(); } public void Dispose() { Undo(); } private void Logon() { try { if (!LogonUser(User, Domain, Password, (int)Type, (int)Provider, out _token)) { int ret = Marshal.GetLastWin32Error(); throw new Exception(String.Format("LogonUser failed with error code : {0}", ret)); } _context = WindowsIdentity.Impersonate(_token); } catch (Exception exception) { var message = exception.Message; Undo(); } } private void Undo() { try { if (_token != IntPtr.Zero) { CloseHandle(_token); _token = IntPtr.Zero; // Clean _token so Undo() could be called several times } if (_context != null) { _context.Undo(); _context = null; // Clean _context so Undo() could be called several times } } catch (Exception exception) { var message = exception.Message; // Releasing resources failed... } } } }
The code that throws the exception:
using (new ImpersonationHelper.Impersonator("WIN-NKLTTMMUEPD", "tester", "tester")) { using (IWebDriver driver = new InternetExplorerDriver()) { driver.Url = _appAddress; return null; } }
Does anyone know how I can prevent this error from occurring? Thank you so much in advance.