selenium web driver running as different user not getting profile/session of user

9.1k views Asked by At

I have a strange situation where I have modified the selenium web driver code slightly to allow the driver service to be launched under a different user, changes to the code from github are:

public void Start()
    {
        this.driverServiceProcess = new Process();
        if (this.user != null)
        {
            this.driverServiceProcess.StartInfo.UserName = user.Name;
            this.driverServiceProcess.StartInfo.Password = user.Password;
            this.driverServiceProcess.StartInfo.Domain = user.Domain;
        }
        this.driverServiceProcess.StartInfo.FileName = Path.Combine(this.driverServicePath, this.driverServiceExecutableName);
        this.driverServiceProcess.StartInfo.Arguments = this.CommandLineArguments;
        this.driverServiceProcess.StartInfo.UseShellExecute = false;
        this.driverServiceProcess.StartInfo.CreateNoWindow = this.hideCommandPromptWindow;
        this.driverServiceProcess.Start();
        bool serviceAvailable = this.WaitForServiceInitialization();

        if (!serviceAvailable)
        {
            string msg = "Cannot start the driver service on " + this.ServiceUrl;
            throw new WebDriverException(msg);
        }
    }

where the user details are passed in from my external code in the call to instantiate the web driver:

new ChromeDriver(userName, password, domain);

or

new InternetExplorerDriver(ieOptions, userName, password, domain);

and propagated through.

This successfully launches the chrome driver under the required user credentials, but has a problem with IE.

Additionally the chrome driver does not have the same behavior as chrome launched as the given user manually (i.e. not through a selenium driver). Specifically the automatic passing of user credentials on an NTLM challenge does not occur.

I have discovered that if I have an interactive session running as the desired user (simply use runas /user:<theUser> cmd.exe from the command line and leave the session open) then all of the functionality of the the browsers is as expected when launched through the selenium web driver, including automatically responding to the NTLM challenge.

If I use Process.Start() to launch cmd.exe as the desired user before creating the web driver this does not work.

My question is this:

What is different about launching a process programatically (using Process.Start()) compared to launching an interactive session of the process from the command line?

And is there any way I can faithfully reproduce the effect of launching a session from the command line in code so that I can automate the process and get my web drivers to perform as I desire?

note: I tried launching the webdriver using .net impersonation (as suggested here and here) rather than modifying the selenium code to run the driver service under another user, but the requests sent from the driver to a server were all sent under my user rather than the one specified by the impersonation (see here)

2

There are 2 answers

1
JimEvans On BEST ANSWER

This technique is no longer required in current Selenium .NET sources. The DriverProcessStarting event now allows the user to modify the ProcessStartInfo object used to start the driver service process. The code to accomplish this would look something like the following:

Assuming your user object looks something like this:

public class User
{
    public string UserName { get; set; }
    public SecureString Password { get; set; }
    public string Domain { get; set; }
    public bool LoadUserProfile { get; set; }
}

You could use something like the following:

public IWebDriver StartInternetExplorerDriver(InternetExplorerOptions options, User user)
{
    InternetExplorerDriverService service = InternetExplorerDriverService.CreateDefaultService();
    service.DriverProcessStarting += (object sender, DriverProcessStartingEventArgs e) =>
    {
        e.DriverServiceProcessStartInfo.UserName = user.UserName;
        e.DriverServiceProcessStartInfo.Password = user.Password;
        e.DriverServiceProcessStartInfo.Domain = user.Domain;
        e.DriverServiceProcessStartInfo.LoadUserProfile = user.LoadUserProfile;
    };

    return new InternetExplorerDriver(service, options);
}
0
Pedro Luz On

Did you try this setting?

this.driverServiceProcess.StartInfo.LoadUserProfile = true;