Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selenium Chrome 60 Headless Handle Basic Authentication SAML Dialog over HTTPS

Chrome 59 removed support for https://user:[email protected] 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.

like image 514
IanC Avatar asked Jul 28 '17 13:07

IanC


1 Answers

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:[email protected] 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'] ); 
like image 102
Cory Avatar answered Oct 03 '22 11:10

Cory