22

I'm trying protractor to write a few tests in a non angular application. I have to login in a page trough basic authentication in google chrome, but i have no idea how.

Authentication box

I already tried baseUrl: 'https://username:password@url' and capabilities: { 'browserName': 'chrome', 'chromeOptions' : { args: ['--login-user=foo', '--login-password=bar'] } }

But none if these worked for me. Anyone knows how to do it? I'm having some hard time on it.

andrepm
  • 867
  • 4
  • 13
  • 31
  • Keep in mind that you can [turn off basic authentication for known IP addresses](http://stackoverflow.com/questions/3649852/allow-ip-address-without-authentication) (i.e. your CI server). – fracz Sep 09 '15 at 21:02

7 Answers7

32

You can set the URL as http://username:password@yourdomain.example. Chrome will handle it!

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Nuno Ferreira
  • 331
  • 3
  • 3
  • 1
    How would you pass the username with the domain? I have tried this approach but it fails when the username has the pattern http://domain\user:pass@www.somesite.com – aplon Oct 18 '16 at 01:21
  • I tried all combination of username and password it did not work for me – Aniruddha Das Mar 13 '17 at 17:44
  • 1
    just in case anyone else is wondering, the answer to aplon's question is to escape the backslash with %5C so it would be http://domain%5Cuser:pass@www.somesite.com – becixb Apr 17 '17 at 05:28
  • 1
    This will no longer work with Chrome 59+(https://www.chromestatus.com/features/5669008342777856) – Nixie May 29 '17 at 13:42
  • I have a site `http://example.com/test` so i gave `baseURL` as `http://username:password@example.com/test` but its getting timed out and not loading. – G.S Abhaypal Sep 08 '17 at 12:59
  • Not working if you use a rest api with a different domain. – R3tep Sep 18 '17 at 15:09
9

The short answer is there is no easy way of doing it on chrome because they do not support modifying request headers -- see https://code.google.com/p/selenium/issues/detail?id=141 (title says response headers, but if you read it, it's for all headers).

That being said, there are ways to do it, albeit difficult.

1) Find a chrome extension/plugin that allows you to modify header. A simple search bring up many of them: https://chrome.google.com/webstore/search/modify%20header. You'll need to add the plugin to webdriver: see Is it possible to add a plugin to chromedriver under a protractor test?.

2) You can use browsermob-proxy (https://github.com/lightbody/browsermob-proxy); this way you route your traffic through the proxy, which would add the headers for you. From the docs:

POST /proxy/[port]/auth/basic/[domain] - Sets automatic basic authentication for the specified domain
Payload data should be json encoded username and password name/value pairs (ex: {"username": "myUsername", "password": "myPassword"}

There's a node project that may help you, https://github.com/zzo/browsermob-node, but you would still need to set up your proxy server yourself.

Both ways for chrome are complex, but would get you what you want. (or you can stick with firefox and follow Robert's answer)

Community
  • 1
  • 1
hankduan
  • 5,994
  • 1
  • 29
  • 43
5

As of version 59 Chrome no longer supports URLs with embedded credentials.

To work around this I wrote the authenticator-browser-extension Node module, which might be useful if you're using Protractor, WebDriver.io or similar test runners.

To use the module install it from npm:

npm install --save-dev authenticator-browser-extension

And import in the protractor.conf.js:

const { Authenticator } = require('authenticator-browser-extension');

exports.config = {
    capabilities: {
        browserName: 'chrome',

        chromeOptions: {
            extensions: [
                Authenticator.for('username', 'password').asBase64()
            ]
        }
    },
}

Pro tip: remember not to commit your credentials with your code, consider using env variables instead.

Hope this helps!

Jan

Jan Molak
  • 4,426
  • 2
  • 36
  • 32
  • 1
    I was not able to make it work, the extension does not do anything. – Rami Sharaiyri Dec 13 '19 at 11:29
  • Hey Rami, `authenticator-browser-extension` has no reported issues at the moment, and has been thoroughly tested to make sure that it's working as advertised. If you have found an issue, please report it on Github so that it can be investigated, Thanks! https://github.com/jan-molak/authenticator-browser-extension/issues – Jan Molak Dec 13 '19 at 14:08
  • I did manage to make it work. It does not work with incognito. And how do you move credentials to env variables? It seems impossible. Env cannot be imported to the protractor config file. – aycanadal Jan 18 '21 at 16:07
  • 1
    "Env cannot be imported" - try using `process.env.YOUR_ENV_VAR_NAME` – Jan Molak Jan 18 '21 at 17:27
  • ahhh, so this is for using windows env variables not the angular environment.ts? – aycanadal Jan 19 '21 at 10:05
  • Yes, yes indeed. Protractor doesn't have access to Angular environment.ts files. I've added a link to Node.js process.env to make it a bit more obvious and avoid confusion. – Jan Molak Jan 19 '21 at 23:46
4

It's because Firefox doesn't trust any site by default with sending the Windows auth info over. Even if you change it in the configurations manually, it won't affect protractor because it opens Firefox with an isolated configuration each time you run your end to end tests.

You'll need to programatically set up a Firefox profile and set its preferences such that it would trust localhost (or some other website, depending where the pages are loaded from)

First, check out this example. It shows how you can set up the profile and how you can set preferences.

https://github.com/juliemr/protractor-demo/tree/master/howtos/setFirefoxProfile

What it does is that it modifies the homepage for each new tab. In the same manner (with the firefoxProfile.setPreference method) you can change the preferences responsible for trusting websites. They're called "network.automatic-ntlm-auth.trusted-uris" and "network.negotiate-auth.delegation-uris". You'll need to set them both to "localhost". (Again, if they're at some other place, it's obviously that URL)

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Robert
  • 197
  • 11
  • Thanks for the complete answer. But i'm looking for an solution for chrome :( – andrepm Dec 03 '14 at 16:48
  • Oh, sorry then. I have had the exact same issue today with Firefox, and I thought you have been having the same problem and I would get back to you when I'm done. Anyway, I am not sure why it does that in chrome. I hope you find an answer :) – Robert Dec 03 '14 at 19:21
0

hankduan's browsermob-proxy solution worked for me on Chrome - but the latest revisions of browsermob are using a thing called littleproxy which does not support auth headers. Thusly I had to do browsermob-proxy -port 9090 --use-littleproxy false, which got things working.

tkell
  • 1
0

You may use Windows Credentials Manager to avoid this pop-up being constantly shown on every attempt to log in.

Add your credentials to the 'Generic' category there, restart browser (including background apps running).

Some explanation I currently have: this pop-up is not 'browser' specific, it is 'in the middle', between browser and domain credentials verification. Thus browser features (save password, autofill) do not work completely. By the same reason Protractor / Selenium etc. do not have complete control over that pop-up - it is by design of the domain authentication.

As not completely sure if it is the only reason there are some other hints: - you may also need to add your site to the IE (IE, not Chrome) list of trusted sites (Chrome grabs information from there); - check "Automatic logon with current user name and password" in IE (not Chrome) - may not work if credentials you are using for the site are different from those you use to login to the machine.

RamanS
  • 1
  • 1
0

If you're reading this in 2019, with Angular 7/8, consider this:

https://www.npmjs.com/package/authenticator-browser-extension

I find it much easier than the solutions suggested above.

AsGoodAsItGets
  • 2,886
  • 34
  • 49
  • Did you manage to make it work ? in my case it does nothing, absolutely nothing :( – Rami Sharaiyri Dec 13 '19 at 11:23
  • Could you please share how you integrated it ? are you using latest chrome webdriver ? – Rami Sharaiyri Dec 13 '19 at 15:30
  • Yes, I'm using the latest webdriver. To ensure that, I added a `pree2e` task in my package.json: `"pree2e": "cd ./node_modules/protractor/ && npm i webdriver-manager@latest && cd ../.. && webdriver-manager update"`. The e2e task is changed thus: `"e2e": "ng e2e --webdriver-update false"`. But these are unrelated to the authentication. After adding the npm module as a dev dependency, I put this in my protractor.conf.js: `capabilities: { 'browserName': 'chrome', chromeOptions: { extensions: [ Authenticator.for(protractor_user, protractor_password).asBase64() ] } }`. Hope it helps. – AsGoodAsItGets Dec 13 '19 at 16:27
  • Exactly what I have done... but it won't fill up the password within the pass prompt ... – Rami Sharaiyri Dec 16 '19 at 10:04
  • Then maybe your type of authentication is different. Also, I don't know if you've already read this in the npm package notes, but this won't work with headless Chrome. And by the way, this doesn't "fill up the password within the pass prompt", i.e. there's no visual form to fill in, the login/authentication is done transparently, you don't see any pop-up prompt. – AsGoodAsItGets Dec 16 '19 at 13:04