19

I am trying to handle an authentication pop-up in one of my new Webdriver scripts. I have a working solution for IE, but I am struggling with Chrome. IE was as simple as following the advice on [this page]:How to handle authentication popup with Selenium WebDriver using Java. That thread doesn't show a great solution for Chrome, although several commentors point out, that the solution does not work for Chrome. The problem is, when you try to do the below code on Chrome, the login popup isn't an Alert.

 WebDriverWait wait = new WebDriverWait(driver, 10);      
 Alert alert = wait.until(ExpectedConditions.alertIsPresent());     
 alert.authenticateUsing(new UserAndPassword(**username**, **password**));

It's not a windows level () authentication pop-up, the web page is simply password protected. I know there are several other instances of this question on Stack Overflow, but I don't see any more recently than 2 years old. I am hoping there is a better solution now in 2017. Thanks in advance.

Community
  • 1
  • 1
Travis Needham
  • 385
  • 1
  • 4
  • 12
  • 1
    Can you share the website? – Guy Feb 08 '17 at 13:55
  • 1
    I would love to, but we have had several security issues in the last 2 years here, and I know my manager would be nervous about my sharing the link. It is a public facing dev site, which is why they have password protected it. – Travis Needham Feb 08 '17 at 14:33
  • Have you looked at this? http://seleniumwebdrivertrainings.com/how-to-perform-basic-authentication-for-firefoxdriver-chromedriver-iedriver-in-selenium-webdriver/ – IamBatman Feb 08 '17 at 16:00
  • That site suggests the same as others, namely: create an instance of FFdriver with a custom profile, and then use the http://user:pass@domain.com trick. When I try it, it doesn't work. Interestingly, if I try that URL manually in a regular FF browser I get the following message: You are about to log in to the site “domain.net” with the username “autotest”, but the website does not require authentication. This may be an attempt to trick you. Is “domain.net” the site you want to visit? – Travis Needham Feb 09 '17 at 18:56
  • check this answer, with selenium 4 it's easy https://stackoverflow.com/a/67321556/7604647 – Pavel Apr 29 '21 at 16:41

5 Answers5

19

May be helpful for others to solve this problem in chrome with the help of chrome extension. Thanks to @SubjectiveReality who gave me this idea.

Sending username and password as part of url like https://username:password@www.mytestsite.com may be helpful if same server performs both authentication and hosts the application. However most corporate applications have firmwide authentications and app server may reroute the request to authentication servers. In such cases, passing credentials in URL wont work.

Here is the solution:

#Step1: Create chrome extension#

  1. Create a folder named 'extension'
  2. Create a file named 'manifest.json' inside 'extension' folder. Copy below code into the file and save it.

{ "name":"Webrequest API", "version":"1.0", "description":"Extension to handle Authentication window", "permissions":["<all_urls>","webRequest","webRequestBlocking"], "background": { "scripts" : ["webrequest.js"] }, "manifest_version": 2 }

  1. Create a file named 'webrequest.js' inside 'extension' folder and copy paste below code into the file and save it.
chrome.webRequest.onAuthRequired.addListener(
function handler(details){
 return {'authCredentials': {username: "yourusername", password: "yourpassword"}};
},
{urls:["<all_urls>"]},
['blocking']);
  1. Open chrome browser, go to chrome://extensions and turn on developer mode

  2. Click 'Pack Extension', select root directory as 'extension' and pack extension. It should create a file with extension '.crx'

#Step2: Add extension into your test automation framework #

  1. Copy the .crx file into your framework
  2. Configure your webdriver creation to load the extension like
options.addExtensions(new File("path/to/extension.crx"));
options.addArguments("--no-sandbox");
  1. Invoke your webdriver and application URL
  2. You wont see the authentication popup appearing as its handled by above extension

Happy Testing!

References:

http://www.adambarth.com/experimental/crx/docs/webRequest.html#apiReference https://developer.chrome.com/extensions/webRequest#event-onAuthRequired chrome.webRequest.onAuthRequired Listener https://gist.github.com/florentbr/25246cd9337cebc07e2bbb0b9bf0de46

Bhuvanesh Mani
  • 1,394
  • 14
  • 23
  • Nice! Another way to accomplish is to add the extension unpacked as an argument, like `options.AddArgument(@"--load-extension=" + Path.GetTempPath() + "\\extensionSource");`, where you save your .js and manifest to the path of your choosing – Subjective Reality May 24 '19 at 18:07
  • 2
    Work with few updates, need to check the following urls https://stackoverflow.com/questions/16612968/chrome-webrequest-onauthrequired-listener and https://stackoverflow.com/questions/48757424/runtime-error-on-chrome-extension since few thing has been changed and the current code does not work – user1610308 Jun 25 '19 at 17:40
  • I have problems getting this working. addListener has now been deprecated so unsure what to use and when I go to generate a Pack Extension I get a Failed to output private key at root directory, despite this being listed as optional? – nocturnalsteve Nov 28 '19 at 07:30
  • I have my code in my local machine and I am running my testcase in virtual machine to which I don't have any access. I have tried robot ( co-ordinate) method which is not working again. By following above provided solution where the .crx file will get generated. What should I do to handle the above situation? @Bhuvanesh Mali – Dolly Apr 15 '20 at 05:09
  • You will create the .crx file in your local machine. Couple this .crx plugin with your remote driver instance which will be sent to your remote machine and plugin will get eventually loaded. Even i am running my script on remote selenium grid and this works fine. – Bhuvanesh Mani Apr 16 '20 at 12:48
10

*edit Chrome no longer supports this.

Isn't that a "restricted" pop-up that can be handled by prepending the address with username and password?

Instead of driver.get("http://www.example.com/"); go for driver.get("http://username:password@www.example.com");.

Peter Bejan
  • 405
  • 3
  • 13
Grzegorz Górkiewicz
  • 4,496
  • 4
  • 22
  • 38
  • 1
    I have tried this, and it doesn't work for me. It may be an issue with the way our website is prompting for credentials, or maybe I have not properly setup Chrome to handle http://user:pass@www.address.com? – Travis Needham Feb 08 '17 at 14:28
  • So this was the answer. I was trying to do "http ://username:password@www.domain.com". I needed to be doing "httpS://username:password@domain.com". – Travis Needham Feb 10 '17 at 16:50
  • @TravisNeedham I am also trying but it doesn't work for me. My password contain @ already. So how can I handle in this case ? Pls suggest – Vaibhav_Sharma Jun 15 '17 at 07:52
  • 14
    Chrome no longer supports this. https://www.chromestatus.com/feature/5669008342777856 Answer is out of date. – Tinman Jun 16 '17 at 02:54
  • @Vaibhav_Sharma I would change my password and remove the @ in it. I don't think there is a way to escape it. – Travis Needham Jun 16 '17 at 12:36
  • 2
    @Vaibhav_Sharma This still works in chrome. But we need to carefully observe how web app is getting authenticated. For e.g., app url may be https://app.url however after hitting the url, it redirects to https://auth.server.url. So if you append username and password into app.url it wont work. It should be appended to auth.server.url. Hope this helps. – Bhuvanesh Mani May 21 '19 at 19:59
7

Updated answer of the solution provided by @Bhuvanesh Mani

manifest.json


    {
        "name": "Webrequest API",
        "version": "1.0",
        "description": "Extension to handle Authentication window",
        "permissions": [
            "webRequest",
            "webRequestBlocking",
            "<all_urls>"
        ],
        "background": {
            "scripts": [
                "webrequest.js"
            ]
        },
        "manifest_version": 2
    }

webrequest.js


    chrome.webRequest.onAuthRequired.addListener(function(details){
        console.log("chrome.webRequest.onAuthRequired event has fired");
        return {
                authCredentials: {username: "yourusername", password: "yourpassword"}
            };
    },
    {urls:["<all_urls>"]},
    ['blocking']);

Not certain why the '--no sandbox' option is required, but for me this is not required.

I did need to perform a registry edit to allow adding extensions since this is disabled with a corporate AD policy:

  • Open regedit.exe as admin
  • navigate to Computer\HKEY_USERS\
  • Change the REG_SZ value that is now set to * to for example -.
  • restart the chrome instance in which you want add extensions to.

The only difference with the original answer is the url's that also need to be present in the permissions.

extra's
if you want to see console output, turn on developer mode and click on the Inspect views background page for your extension in the extensions screen in Chrome

obiwankoban
  • 143
  • 2
  • 6
1

I know your situation is Java, but this might be helpful. I was able to get past the alert using this approach in C#:

// I am using a static instance of the driver for this.
Driver.Instance.Navigate().GoToUrl(url);
var alert = Driver.Instance.SwitchTo().Alert();
alert.SendKeys($"{Driver.user_name}" + Keys.Tab + $"{Driver.user_password}" + Keys.Tab);
alert.Accept();
Driver.Instance.SwitchTo().DefaultContent();

I then utilized a test user account as the values of the user_name and password.

joshmcode
  • 3,471
  • 1
  • 35
  • 50
  • 1
    I get a timeout on GoToUrl(url), even though the alert is displayed. Chrome v74 with chromedriver v74. – Subjective Reality May 07 '19 at 19:56
  • This isnt working for me because as @SubjectiveReality said, its stuck in invoking URL itself which displaying the user authentication popup... sad, couldnt find the solution for this problem yet! – Bhuvanesh Mani May 21 '19 at 18:51
  • 1
    @BhuvaneshMani you can launch chrome with an unpacked extension with `chrome.webRequest.onAuthRequired.addListener`, though that doesn't work in headless mode. – Subjective Reality May 21 '19 at 22:16
  • @SubjectiveReality That seems to be attractive solution, do you have java code handy that i can use this listener approach? Meanwhile i will try it out. – Bhuvanesh Mani May 22 '19 at 16:40
  • Never mind, i have solved this problem by creating extension. – Bhuvanesh Mani May 22 '19 at 19:51
  • @SubjectiveReality I have created extension and successfully loading while creating the session in remote node. But after browser loads with extension, its just not responding to selenium webdriver anymore. Even the first line, driver.get(URL) fails with message as Timed out receiving message from renderer: 60.0. It responds if i load browsers without extensions. So looks like i need to do something with extension? Like creating a background page for extension? – Bhuvanesh Mani May 23 '19 at 21:58
  • @BhuvaneshMani you may need to add the `--no-sandbox` argument to your options, and possibly before the extension. Also, last I looked, loading unpacked extensions is not supported in conjunction with `--headless`, in case that is tripping you up. – Subjective Reality May 23 '19 at 22:14
  • @SubjectiveReality Thanks, I have no sandbox, loading extension before that and my tests are NOT headless. After long hours, i found that its NOT working only for chrome version 73.0 and working perfectly in all other chrome versions. Looks like version specific chrome bug. – Bhuvanesh Mani May 24 '19 at 02:01
  • OpenQA.Selenium.NoAlertPresentException: 'no such alert (Session info: chrome=97.0.4692.71)' – Luca Ziegler Jan 14 '22 at 11:31
1

Selenium 4 supports authenticating using Basic and Digest auth . It's using the CDP and currently only supports chromium-derived browsers

Java Example :

Webdriver driver = new ChromeDriver();

((HasAuthentication) driver).register(UsernameAndPassword.of("username", "pass"));

driver.get("http://sitewithauth");

Note : In Alpha-7 there is bug where it send username for both user/password. Need to wait for next release of selenium version as fix is available in trunk https://github.com/SeleniumHQ/selenium/commit/4917444886ba16a033a81a2a9676c9267c472894

Rahul L
  • 4,249
  • 15
  • 18
  • This works fine with my local setup but HasAuthentication doesn't supported by remoteWebDriver yet. – sayhan Jul 23 '21 at 11:13