SeleniumHQ / selenium-google-code-issue-archive

Archive, please see main selenium repo
https://github.com/seleniumhq/selenium
345 stars 195 forks source link

Support BASIC and Digest HTTP authentication #34

Open lukeis opened 8 years ago

lukeis commented 8 years ago

Originally reported on Google Code with ID 34

There should be an easy to use API for authenticating using standard HTTP mechanisms

Reported by simon.m.stewart on 2007-11-05 16:13:45

lukeis commented 8 years ago
I think it is worth mentioning that it is possible to do BASIC HTTP authentication --
in an ugly way - even now, by extending the driver.
@Override
protected WebClient newWebClient() {
    WebClient client = super.newWebClient();
    DefaultCredentialsProvider  provider = new DefaultCredentialsProvider();
    provider.addCredentials("username","password");
    client.setCredentialsProvider(provider);
    return client;
    }

Reported by turkoglu.deniz on 2008-08-12 10:02:34

lukeis commented 8 years ago
We are using version 0.6.870 and note that the newWebClient() method signature is
different to that above. We have found that the following works ok. because
newWebClient is called by the default constructor in the super class, you can't just
pass the usernam and password in the constructor, so we hacked about a bit with the
statics:

public class AuthenticatedHtmlUnitDriver extends HtmlUnitDriver {

    public static void setCredentials(String username, String password) {
        USERNAME = username;
        PASSWORD = password;
    }

    private static String USERNAME;
    private static String PASSWORD;

    public AuthenticatedHtmlUnitDriver() {
    }

    @Override
    protected WebClient newWebClient(BrowserVersion browserVersion) {       
        System.out.println("Logging in with: [username:" + USERNAME + "]");
        WebClient client = super.newWebClient(browserVersion);
        DefaultCredentialsProvider provider = new DefaultCredentialsProvider();
        provider.addCredentials(USERNAME, PASSWORD);
        client.setCredentialsProvider(provider);
        return client;
    }

}

Reported by jim.barritt on 2009-04-14 13:10:51

lukeis commented 8 years ago
Slightly nicer version is to have a factory method instead of setCredentials:

public static WebDriver create(String username, String password) {
        USERNAME = username;
        PASSWORD = password;
        return new AuthenticatedHtmlUnitDriver();
    }

Reported by jim.barritt on 2009-04-14 13:17:41

lukeis commented 8 years ago
I can only find the WebClient stuff inside HtmlUnit. Is there any solution/work
around to make this work with say the InternetExplorerDriver?

Reported by per.olesen on 2009-07-03 06:59:15

lukeis commented 8 years ago
If you’re using the Firefox driver there is an even dirtier work-around. It’s
possible to specify the username and password on the URL. e.g. 
http://username:password@www.basicauthprotected.com/.

The next hurdle is an anti-phishing dialogue box. This can however be suppressed
using aboubt:config, creating a new entry named network.http.phishy-userpass-length
with a type of Integer and a value of 255.

Reported by robdkay on 2010-04-27 11:02:33

lukeis commented 8 years ago

Reported by jari.bakken on 2010-06-17 00:28:34

lukeis commented 8 years ago
Having also some issues (dialog box) with Basic Authentication on IE. As read in the
OpenQA Wiki this is handled automatically by the remote control. There should also
be such a feature for the InternetExplorerDriver. Is there any workaround so far?

Reported by roland.schaer on 2010-07-20 08:38:41

lukeis commented 8 years ago
Code for Handling HTTP Basic Authentication for FireFox driver is as follows. I know
this is a crude way but its working for now.

FirefoxProfile profile = new FirefoxProfile();
profile.setPreference("network.http.phishy-userpass-length", 255);
driver = new FirefoxDriver(profile);
driver.get(http://username:password@www.basicauthprotected.com/);

Reported by arun280780 on 2010-12-07 09:05:22

lukeis commented 8 years ago
Doesn't  work in my situation ( I have domain\username and password  )

http://domain\username:password@www.basicauthprotected.com

Reported by Mochalin.Igor on 2011-04-26 14:15:17

lukeis commented 8 years ago
Additional information 
doesn't work  in FireFox and  Chrome  

Reported by Mochalin.Igor on 2011-04-26 14:30:10

lukeis commented 8 years ago
How to prevent the anti phishing dialogue box in safari. Any pointers

Thanks 

Reported by crab19 on 2011-05-27 22:45:21

lukeis commented 8 years ago
Issue 1786 has been merged into this issue.

Reported by simon.m.stewart on 2011-06-08 13:12:38

lukeis commented 8 years ago
does anyone know if this issue is logged in the java forum somewhere.  i am having the
same problem with selenium rc/java.  i am also attempting this with domain\username.
 i keep reading that selenium rc "handles" basic authentication for me - yet there
is no explanation for this that i can find.  i have attempted everything this issue
mentions plus the following and nothing works so far.  should i create and issue for
this with a java implementation or can this issue be modified??

i have tried this approach as well with no luck (addCustomRequestHeader)
http://stackoverflow.com/questions/3021602/http-basic-auth-via-url-in-firefox-does-not-work

i apologize in advance if i have hijacked this issue in any way.  please let me know.

thanks!
-allen

Reported by otwoblue on 2011-06-20 07:25:30

lukeis commented 8 years ago
Firefox workaround - store your password in firefox manually. Reuse this existing profile
in code, for example:
    new FirefoxDriver(profile)

Reported by whittet on 2011-09-02 15:19:52

lukeis commented 8 years ago
Maybe I'm naive and correct me if I'm wrong, but for comment 16 isn't the Firefox passwords
only for websites? I believe no browser ever store's your HTTP Basic/Digest authentication
username & passwords. It may get cached (by server?) for the browser session once you
log in, but for every new session you have to login again.

Stored passwords are only for website form logins.

Reported by mangaroo on 2011-09-02 19:39:06

lukeis commented 8 years ago
Has anyone tried escaping the \ in domain\username for Firefox Basic HTTP auth? For
example,

http://domain%5cusername:password@www.basicauthprotected.com

I know for one of our sites we have to escape symbols like % and ! in the password
or it does not work.

Reported by darrell.grainger on 2011-09-03 02:44:35

lukeis commented 8 years ago
Unfortunately the http://user:pass@address.tld is not always a usable workaround, currently
I am facing the authentication window after I submitted a (language setting) form.
It should be considered when designing a solution.

Reported by jr.visko on 2011-09-23 09:00:28

lukeis commented 8 years ago
Couple of things I've done to handle cases on various browsers for basic authentication:

First of all, I always pass via the URL with http://user:pass@domain.com/folder_with_auth_required/

There are less issues on certain browsers if the trailing slash is included (notably
Opera) for reasons I won't detail here. 

Many browsers will still give a prompt for the user/pass even though it's in the URL,
or some will ask for confirmation before proceeding.  There are profile settings in
the browsers that can turn this off, notably FF as mentioned above.

FirefoxProfile profile = new FirefoxProfile();
profile.setPreference("network.http.phishy-userpass-length", 255); 

With version of selenium before 2.6, Firefox needed this setting but it is included
for you in version 2.6+ so is unnecessary:

With OperaDriver, you can disable the preference "Enable Trust Rating" to help, but
depending on the Opera version you will still get a confirmation prompt.  In those
cases, I have a timeout thread that basically presses the Enter key via Robot so the
driver can continue.

For those of you commenting that this should be fixed asap, remember this is open source
project and feel free to download the source, make fixes, and submit those patches.
 At that point you may see the difficulty involved in getting solutions to work cross-browser.

What I am basically saying here, is that yes, submit comments and well documented issues,
but put the time in where things aren't working ideally to create your own work arounds.
 I'm able to use basic auth across all browser drivers but it's not going to work out
of the box.  

Reported by luke.kende on 2011-09-26 03:43:20

lukeis commented 8 years ago
On comment 20, I wonder how often the workarounds for cross-browser support are non
destkop GUI based (AutoIt, Sikuli, whatever Robot). This includes stuff like file download
& upload beyond the authentication, and applies even more for Selenium RC. The reason
to bring this up is that sadly, this GUI type of workaround is (or can be) then broken
in a Selenium Grid or SauceLabs deployment, which don't have a complementary infrastructure
to pair GUI automation with it to handle such workarounds. That kind of pairing integration
would be worth thinking if we ever still need to pair GUI automation with browser automation.

Reported by mangaroo on 2011-09-26 06:41:37

lukeis commented 8 years ago
I am using the "network.http.phishy-userpass-length" setting described in comment 20,
but since the page I am testing is using Ajax heavily, I also need to set this on all
subsequent XHR requests. I have done this by using a proxy (littleshoot) and it works
quite well. In addition to the "network.http.phishy-userpass-length" setting I use
the following:

      profile.setPreference("network.proxy.type", 1);
      profile.setPreference("network.proxy.http", "127.0.0.1");
      profile.setPreference("network.proxy.http_port", 8080);
      profile.setPreference("network.proxy.no_proxies_on", "");

Then in my test, in @BeforeClass, I start the proxy like this:

      HttpRequestFilter requestFilter = new HttpRequestFilter() {
         @Override
         public void filter(HttpRequest httpRequest) { httpRequest.addHeader("Authorization",
"Basic " + BASE64EncodedAuthorizationString); }
      };

      final HttpProxyServer server = new DefaultHttpProxyServer(8080, requestFilter,
new HashMap<String, HttpFilter>());
      server.start();

I've also tried removing the "network.http.phishy-userpass-length" property, but it
is still required with selenium-firefox-driver-2.16.1 at least.

Reported by stian.lindhom.lemontree.no on 2012-01-12 07:09:59

lukeis commented 8 years ago
This is very important feature. Currently we're thinking about selenium usage for a
major project which uses Basic Http Authentication and this issue is the only thing
which stops us. Does somebody has any estimates?

Reported by bakaev.dmitriy on 2012-01-17 11:04:08

lukeis commented 8 years ago
You have to write your own script for Digest Based Authentication, no
testing tool provides it.

Reported by qasim.zaman@softrove.com on 2012-01-17 11:17:48

lukeis commented 8 years ago
The following proposed solution is not working in Firefox 9.0.1:

FirefoxProfile profile = new FirefoxProfile();
profile.setPreference("network.http.phishy-userpass-length", 255);
driver = new FirefoxDriver(profile);
driver.get(http://username:password@www.basicauthprotected.com/);

Reported by rui.abreu on 2012-01-17 18:14:23

lukeis commented 8 years ago
it worked for me like this:

FirefoxProfile profile = new FirefoxProfile();
profile.setPreference("network.http.phishy-userpass-length", 255);
profile.setPreference("network.automatic-ntlm-auth.trusted-uris", "<host>");
driver = new FirefoxDriver();
selenium = new WebDriverBackedSelenium(driver, "http://<user>:<password>@<host>");

Reported by krueger.fab on 2012-01-21 22:30:49

lukeis commented 8 years ago

This one is working for me to certain extent.

web1.get("http://<userName>:<password>@<URL>");

I am getting the problem when I click a button and it is asking for Authentication

In this case I am not able to handle. 

Hope this enhancement handle this :)

Reported by sharan.m.mailar on 2012-03-06 07:58:57

lukeis commented 8 years ago
Hey,

I was able to find some workaround for this:
selenium.start("addCustomRequestHeader=true");
selenium.windowMaximize();
selenium.addCustomRequestHeader( "Authorization","Basic "+"YWRpZGFzOmFkaWRhczEyMyM="
);

where YWRpZGFzOmFkaWRhczEyMyM= is the encoded password. This works fine with me :)

Reported by mayank0905 on 2012-03-06 09:33:57

lukeis commented 8 years ago
Hi.

I tried the code below for web proxy authorization.
(using selenium-java-2.20.0 & junit3.8)
But I missed.

package com.example;

import junit.framework.TestCase;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverBackedSelenium;
import org.openqa.selenium.ie.InternetExplorerDriver;

import sun.misc.BASE64Encoder;

public class SampleTest extends TestCase {

    public void test01() {

        String baseUrl = "http://www.google.co.jp/";
        String proxy_user = "my proxy username";
        String proxy_passwd = "my proxy password";
        WebDriver driver = new InternetExplorerDriver();
        WebDriverBackedSelenium selenium = new WebDriverBackedSelenium(driver,
                baseUrl);
        BASE64Encoder encoder = new BASE64Encoder();
        String authHeader = encoder.encode((proxy_user + proxy_passwd).getBytes());

        selenium.start("addCustomRequestHeader=true");
        selenium.addCustomRequestHeader("Proxy-Authorization", "Basic" + " "
                + authHeader);

        selenium.open("/");
        selenium.close();

    }

}

java.lang.RuntimeException: Could not start Selenium session: Unsure how to process:
addCustomRequestHeader=true
    at com.thoughtworks.selenium.DefaultSelenium.start(DefaultSelenium.java:125)
    at com.example.SampleTest.test01(SampleTest.java:32)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at junit.framework.TestCase.runTest(TestCase.java:168)
    at junit.framework.TestCase.runBare(TestCase.java:134)
    at junit.framework.TestResult$1.protect(TestResult.java:110)
    at junit.framework.TestResult.runProtected(TestResult.java:128)
    at junit.framework.TestResult.run(TestResult.java:113)
    at junit.framework.TestCase.run(TestCase.java:124)
    at junit.framework.TestSuite.runTest(TestSuite.java:243)
    at junit.framework.TestSuite.run(TestSuite.java:238)
    at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: java.lang.UnsupportedOperationException: Unsure how to process: addCustomRequestHeader=true
    at org.openqa.selenium.WebDriverCommandProcessor.start(WebDriverCommandProcessor.java:92)
    at com.thoughtworks.selenium.DefaultSelenium.start(DefaultSelenium.java:115)
    ... 19 more

Reported by nabedge on 2012-03-12 06:17:42

lukeis commented 8 years ago
I believe the addRequestHeader method only or primarily works for Firefox. And it's
not necessarily supported (yet) in some (RC) language bindings like PHP.

Reported by mangaroo on 2012-03-12 16:59:09

lukeis commented 8 years ago
BTW, there is a solution to send keys in a blind mode, just simulate key press. For
instance: 
SendKeys("myUser");
SendKeys("{TAB}");
SendKeys("MyPassword");
SendKeys("~"); // Enter

Works really awful...  but works... 

Hey, Selenium Guys!! =) Crowd is still waiting for this feature.

Reported by bakaev.dmitriy on 2012-03-20 12:43:28

lukeis commented 8 years ago
i read the whole thread. i am surprised that i did not have this problem with authentication.
my firefox and chrome driver able to do auth via url e.g. http://username:password@google.com

But it's not working on IE. Read on some other thread that new Internet explorer does
not allow auth in urls like this one. 

is someone knows any workaround to get through IE? 

Reported by Rajesh.huria on 2012-04-01 21:51:37

lukeis commented 8 years ago
Issue 3694 has been merged into this issue.

Reported by dawagner on 2012-04-10 21:06:32

lukeis commented 8 years ago
someone helped me with this one.

Fixed the problem by a registry hack for IE.
http://support.microsoft.com/kb/834489

Once thats done you should be able to pass user name and password in the url for login.

Reported by Rajesh.huria on 2012-04-11 08:30:06

lukeis commented 8 years ago
Re: #31, the addRequestHeader method works for all browsers.  For more details, I wrote
up a howto:

http://blog.mogotest.com/2010/06/23/how-to-perform-basic-auth-in-selenium/

However, note that this only works for the RC protocol.  The issue at hand is for WebDriver
support.  That should be doable via a similar mechanism using the BrowserMob Proxy,
although I don't believe anyone has written up docs for it yet.

Reported by nirvdrum on 2012-04-11 09:27:55

lukeis commented 8 years ago
Issue 3265 has been merged into this issue.

Reported by dawagner on 2012-04-11 11:20:53

lukeis commented 8 years ago
Re: #36, I recall seeing the blog post, which I used as reference for trials. My follow
up question to comment #36 is, has anyone confirmed testing that method across a range
of browsers (IE 8, IE9, IE7?, IE6?, Mac/Windows Safari 5, Mac/Windows Safari 4, FF3.6,
FF10, etc.)

In my trial testing it seemed only to work for FF. I'd like to hear a confirmation
as well as see sample code for IE and Safari (in case my code was "incorrect"). Plus
any special configs or startup modes for IE and Safari? Like start up with Selenium
as "*iexproxy" vs "iexplore" and "*safariproxy" vs "*safari".

Also, anyone know whether the method works across all bindings as well or only some,
for example, does it work with PHP?

Reported by mangaroo on 2012-04-11 22:34:26

lukeis commented 8 years ago
When this enhancement will be available ? 

Reported by sharan.m.mailar on 2012-04-23 09:30:24

lukeis commented 8 years ago
Issue 3805 has been merged into this issue.

Reported by dawagner on 2012-04-26 06:04:22

lukeis commented 8 years ago
I would really like to see a standard way(if possible) for this issue and webdriver.
I have seen so many ideas but none that have worked for me yet. I also find getting
changes in to a FF profile to be a pain. Anyone have a good process in place?

Reported by jeffcster on 2012-05-17 11:47:36

lukeis commented 8 years ago
Issue 1862 has been merged into this issue.

Reported by barancev on 2012-05-19 19:19:44

lukeis commented 8 years ago
http://username:password@google.com has stopped working in Chrome as of the v19 (was
working fine with v18). Does anyone else have this problem and do you know of a solution?

Reported by Haitham.Zaben on 2012-05-20 22:52:43

lukeis commented 8 years ago
+1 on 43.

http://username:password@www.basicauthprotected.com/ does not work with Chrome.
Some folks also report problems with IE this way.

Selenium API level solution would be much appreciated!

Reported by czigola on 2012-05-21 17:30:48

lukeis commented 8 years ago
+2 on 43. Chrome is my biggest enemy now because of that...

Reported by brandontylerwilliams on 2012-05-21 17:50:09

lukeis commented 8 years ago
I had to work around it in Chrome by using an extension.

Reported by krisr@chromium.org on 2012-05-21 18:25:29

lukeis commented 8 years ago
@#46 - There's an extension for that?! Please elaborate :D

Reported by brandontylerwilliams on 2012-05-21 18:47:29

lukeis commented 8 years ago
I had to write my own.  I gave an example here: http://code.google.com/p/chromium/issues/detail?id=123150#c36.
 Then someone else add some more steps in http://code.google.com/p/chromium/issues/detail?id=123150#c41.

Reported by krisr@chromium.org on 2012-05-21 19:03:49

lukeis commented 8 years ago
I wonder if that Chrome extension method can be ported to FF and Safari extensions to
workaround the issue here (in case the other FF/Safari workarounds don't work).

Wonder if same thing could apply to IE too. IE (and I think Safari) extensions persist,
so you don't have to load with driver. Once installed, it will be available to browser.

For Safari, could model an extension on (or temporarily incorporate into) SafariDriver
extension.

Reported by mangaroo on 2012-05-21 19:53:40

lukeis commented 8 years ago
public class authenticatio {
    WebDriver driver;
    //DefaultSelenium selenium;
    @Test
    public void setup() throws InterruptedException
    {
    FirefoxProfile profile = new FirefoxProfile();
    //selenium.open("/");
    profile.setPreference("network.http.phishy-userpass-length", 255);
    profile.setPreference("network.automatic-ntlm-auth.trusteduris","www.google.com/");
    driver = new FirefoxDriver(profile);
    driver.get("http://bhargavi.vittalsingh:blackberry1234@@google.com");

}
}

Reported by gavi.bhar on 2012-05-23 08:03:18

lukeis commented 8 years ago
pl help me

Reported by gavi.bhar on 2012-05-23 08:03:43

lukeis commented 8 years ago
When will this feature be available?

Currently, I am using the work around for basic HTTP authentication. However, some
of the application that I use, uses active directory/NT authentication. How do I handle
this?

FirefoxProfile profile = new FirefoxProfile();
        profile.setPreference("network.http.phishy-userpass-length", 255);
        profile.setPreference("network.automatic-ntlm-auth.trusteduris","mydomain.com");
        driver = new FirefoxDriver(profile);
        driver.manage().window().maximize();
        driver.get("http://user1:Test@123@mydomain.com/index.aspx");

How do I handle the @ symbol used for the password?

Reported by ranj27 on 2012-06-21 17:13:51

lukeis commented 8 years ago
@ran...@gmail.com, you need to URL encode user names and passwords. I have '@' in test
user's password and URL encoding worked.

Reported by dkroot2 on 2012-06-21 18:21:42