IEDriverServer Causes Error Using Impersonation

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.

+5
source share
1 answer

I could not reproduce the collapse of the IEDriver .

However, since you put generosity on this question, I would not mind spending a little time trying to find a solution. I have never implemented Windows authentication or tested impersonation before, however I have experience testing UI Automation.

From time to time up to an hour:

  • A sample intranet MVC application using Windows authentication has been created.
  • a new project is added and the basic unit test is configured, which loads the site.
  • impersonation added.

I'm not sure exactly how you implemented your tests, however, I would strongly recommend that you use Seleno for .NET / MVC projects . This is a wrapper around the Selenium web driver (what you are currently using), however it makes user interface testing less painful / fragile, forcing you to use the interface of page objects and page components and reading and writing web page data using strongly typed models representation.

I would also recommend using the SimpleImpersonation library, as this is a safer / more efficient implementation of the Winon API LogonUser function, for example. it uses SafeHandle , and the removal path is cleaner.

The test I wrote

 [Test] public void GivenImpersonatedUser_IsLoggedInCorrectly() { const string domain = "domain"; // . for local machine const string username = "impersonate.username"; const string password = " strongp@ssw0rd1 "; const LogonType logonType = LogonType.Interactive; using (Impersonation.LogonUser(domain, username, password, logonType)) { var page = Host.Instance.NavigateToInitialPage<HomePage>(); Assert.That(page.LoginPanel.LoggedInUserName, Is.EqualTo(string.Format("{0}\\{1}", domain, username))); } } 

This is a Seleno page object called HomePage that uses the reused LoginPanel component.

 public class HomePage : Page { public LoginPanel LoginPanel { get { return GetComponent<LoginPanel>(); } } } public class LoginPanel : UiComponent { public string LoggedInUserName { get { return Find.Element(By.Id("login-username")).Text; } } } 

Seleno host configuration using IEDriver .

 public static class Host { private static readonly InternetExplorerDriver Driver = new InternetExplorerDriver(); public static readonly SelenoHost Instance = new SelenoHost(); static Host() { Instance.Run(c => { c.WithRemoteWebDriver(() => Driver); c.ProjectToTest(new WebApplication(ProjectLocation.FromFolder("WebApplication1"), 61285)); c.UsingLoggerFactory(new ConsoleFactory()); c.UsingCamera("C:\\screenshots"); }); } var codeBase = assembly.CodeBase; var uri = new UriBuilder(codeBase); var path = Uri.UnescapeDataString(uri.Path); return Path.GetDirectoryName(path); } } 

A few other things I learned: - You will get error code 1326 if your username or password is incorrect. - You can use the Process Hacker to confirm that the webdriver process has started with the correct authentication token.

As I said, I could not answer your specific problem, however, try to use the above and comment - with pleasure, help further.

+2
source

Source: https://habr.com/ru/post/1208163/


All Articles