33

Chrome 59 removed support for https://user:password@example.com URLs.

I have a C# selenium test that needs to work with Chrome Version 60 on Windows in 'headless' mode

ChromeOptions options = new ChromeOptions();
options.AddArgument("headless");
driver = new ChromeDriver(chrome, options);

Here is the SAML authentication required dialog I am trying to handle on Windows: Basic Auth Dialog

Based on the answer given here: How to handle authentication popup with Selenium WebDriver using Java) I can see several workarounds for handling this in FireFox, but nothing for Chrome 60 in headless mode.

I've tried the following code to visiting a URL with credentials before visiting the URL under test (without credentials) however it appears there is a bug with Chrome 60.

goTo("http://user:password@localhost"); // Caches auth, but page itself is blocked
goTo("http://localhost"); // Uses cached auth, page renders fine
// Continue test as normal

I can see the following code in Firefox handles the authentication and the dialog never pops up:

FirefoxProfile profile = new FirefoxProfile();
profile.SetPreference("network.automatic-ntlm-auth.trusted-uris", "https://saml.domain.com");
profile.EnableNativeEvents = false;`

I've tried the second approach (using AutoIt) and that works on Chrome 60 but does NOT work on Chrome 60 in Headless mode.

//Use AutoIt to wait 4 seconds for the authentication required dialog to appear
au3.Sleep(4000);
//Use AutoIT to send in the credentials from app.config that are encrypted
au3.Send(USERNAME + "{TAB}" + PASSWORD + "{ENTER}");
//Refresh the page
driver.Navigate().Refresh();

I am hoping there is a better solution now in 2017 and that there is an approach that will work with Chrome 60 in headless mode, any pointers?

Just to be clear: Trying to use embedded credentials will NOT work using chrome v59+ because sub-resource requests will be blocked.

534F
  • 57
  • 6
Ian Ceicys
  • 471
  • 4
  • 8
  • Possible duplicate of [Python Selenium Alert - Prompt username & password is not working](https://stackoverflow.com/questions/45328654/python-selenium-alert-prompt-username-password-is-not-working) – undetected Selenium Jul 28 '17 at 15:32
  • 1
    You can check this [**Question/Discussion/Thread**](https://stackoverflow.com/questions/45345882/selenium-other-way-to-basic-authenticate-than-via-url/45352660?noredirect=1#comment77716943_45352660) as well. – undetected Selenium Jul 28 '17 at 15:58
  • I too still get the login prompt in chrome when running the selenium test. And both suggestions do not work with Chrome 60 in headless mode on Windows. – Ian Ceicys Jul 28 '17 at 16:32
  • 2
    There a another way in selenium - In java it is like below :- WebDriverWait waits = new WebDriverWait(driver, 10); Alert alert = waits.until(ExpectedConditions.alertIsPresent()); alert.authenticateUsing(new UserAndPassword(username, password)); – Shubham Jain Aug 21 '17 at 12:35
  • Try same in C# it should work – Shubham Jain Aug 21 '17 at 12:36
  • Let me know once you will try it out – Shubham Jain Aug 21 '17 at 12:36
  • @ShubhamJain Unfortunately this does not work with chromedriver, I've just tried it myself, and Chrome does not recognise the authentication alert as an alert. It seems it may get fixed at some point: https://bugs.chromium.org/p/chromedriver/issues/detail?id=1917 – Sam Peacey Dec 12 '17 at 08:37
  • Is this only an issue with https or also with http? – Woozar Mar 09 '18 at 12:54

3 Answers3

3

I know this is almost a year old, but this is what ended up working for me in a similar situation. It is true that the authentication pop-up has changed and ChromeDriver doesn't seem to support it or the http(s)://user:password@url.com scheme anymore, but the work-around that I found here seems to do the trick. It was originally written to authenticate a proxy system, but can be modified to work with any authentication system.

Basically you need to make a chrome extension that handles entering the login details on the page. A chrome extension can be added with ChromeOptions.AddExtension(string FilePath) and an extension is just a zip file with a manifest.json and any code files to do the work. Here are the files you'll need.

manifest.json

{
    "version": "1.0.0",
    "manifest_version": 2,
    "name": "Chrome Proxy",
    "permissions": [
        "proxy",
        "tabs",
        "unlimitedStorage",
        "storage",
        "<all_urls>",
        "webRequest",
        "webRequestBlocking"
    ],
    "background": {
        "scripts": ["background.js"]
    },
    "minimum_chrome_version":"22.0.0"
}

background.js

function callbackFn(details) {
    return {
        authCredentials: {
            username: "YOUR_PROXY_USERNAME",
            password: "YOUR_PROXY_PASSWORD"
        }
    };
}

chrome.webRequest.onAuthRequired.addListener(
    callbackFn,
    {urls: ["YOUR_WEBSITE_ADDRESS"]},
    ['blocking']
);
Cory
  • 146
  • 8
  • This approach worked for me while others didn't. I tried getting the login alert and modifying the page URL to include username and password, but both attempts failed. – Bartek Sep 11 '20 at 11:06
0

Perhaps you can perform a previous connection using a XMLHttpRequest using the method setRequestHeader so you can specify the authentication header. After performing a single request you will be authenticated to all the other type of requests. The bigger problem could be XSS, depending on your scenario you maybe can workaround it.

user1039663
  • 1,230
  • 1
  • 9
  • 15
-1

You can use the "MultiPass for HTTP basic authentication" Chrome Extension to handle this.

You can do via GitHub MultiPass for HTTP basic authentication

(or)

Download the extension from Chrome Web Store - MultiPass Chrome Extension

(Or)

Download the extension as crx. You can get it as crx from chrome-extension-downloader

Once you download the Extension as crx File - Configuring the same into your Test/Source is very simple.

And this can be tested using the Sample Basic Auth-Site.

public class ChromeAuthTest {

    WebDriver driver;

    public ChromeAuthTest() {
        System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
    }

    private void initDriver() {
        ChromeOptions cOptions = new ChromeOptions();
        cOptions.addExtensions(new File("MultiPass-for-HTTP-basic-authentication_v.crx"));
        driver = new ChromeDriver(cOptions);
        configureAuth(
                "https://the-internet.herokuapp.com/basic_auth",
                "admin",
                "admin");
    }

    private void configureAuth(String url, String username, String password) {
        driver.get("chrome-extension://enhldmjbphoeibbpdhmjkchohnidgnah/options.html");
        driver.findElement(By.id("url")).sendKeys(url);
        driver.findElement(By.id("username")).sendKeys(username);
        driver.findElement(By.id("password")).sendKeys(password);
        driver.findElement(By.className("credential-form-submit")).click();
    }

    public void doTest() {
        initDriver();
        driver.get("https://the-internet.herokuapp.com/basic_auth");
        System.out.println(driver.getTitle());
        driver.quit();
    }

    public static void main(String[] args) {
        new ChromeAuthTest().doTest();
    }
}

NOTE: This is taken from this Answer.

Hope this helps!

  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/low-quality-posts/22111362) – Mark Rotteveel Feb 04 '19 at 10:01
  • @MarkRotteveel - Added the essentials - thanks for the Review. Please do let me know if anything is still missed/if my answer can be improved. – Aravamudhan Sivanandam Feb 04 '19 at 10:22