Handling Basic Authentication in Selenium WebDriver

Handling Basic Authentication in Selenium WebDriver

3 July 2024 Stephan Petzl Leave a comment QA

When using Selenium WebDriver to test web applications, you might encounter scenarios where the site requires Basic Authentication. This presents a challenge, as Selenium WebDriver does not natively support sending custom headers in HTTP requests. However, there are several solutions to bypass this limitation.

Using the URL with Embedded Credentials

One common method is embedding the credentials directly into the URL. This technique is simple and effective:

self.base_url = "http://user:pass@host"

In Java, this can be implemented as follows:

public void login(String username, String password){
    WebDriver driver = getDriver();
    String URL = "http://" + username + ":" + password + "@" + "link";
    driver.get(URL);
    driver.manage().window().maximize();
}

This approach works well for initial requests but may have limitations with subsequent AJAX calls or other HTTP requests.

Configuring FirefoxProfile for Basic Authentication

Another method involves configuring the FirefoxProfile to handle Basic Authentication:

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

This configuration prevents Firefox from prompting for credentials and directly uses the provided username and password.

Using Chrome Extension for Headers

For Chrome, a more recent solution involves creating a tiny Chrome extension to add the necessary headers:

File authExtension = new SeleniumChromeAuthExtensionBuilder()
    .withBasicAuth("Ali Baba", "Open sesame")
    .withBaseUrl("https://example.org/*")
    .build();

try {
    ChromeOptions chromeOptions = new ChromeOptions();
    chromeOptions = chromeOptions.addExtensions(authExtension);
    webDriver = new ChromeDriver(chromeOptions);
} finally {
    authExtension.delete();
}

This approach is highly flexible and ensures that all requests to the specified base URL include the authentication headers.

Setting Up a Proxy

Another advanced method is setting up a proxy to handle the headers for your test. This can be done using tools like Proxy Py:

from proxy.http.proxy import HttpProxyBasePlugin
from proxy.http.parser import HttpParser
from typing import Optional
import base64

class BasicAuthorizationPlugin(HttpProxyBasePlugin):
    def before_upstream_connection(self, request: HttpParser) -> Optional[HttpParser]:
        return request

    def handle_client_request(self, request: HttpParser) -> Optional[HttpParser]:
        basic_auth_header = 'Basic ' + base64.b64encode('webelement:click'.encode('utf-8')).decode('utf-8')
        request.add_header('Authorization'.encode('utf-8'), basic_auth_header.encode('utf-8'))
        return request

    def on_upstream_connection_close(self) -> None:
        pass

    def handle_upstream_chunk(self, chunk: memoryview) -> memoryview:
        return chunk

This method is particularly useful for handling HTTPS traffic and offers a high degree of customization.

Conclusion

While Selenium WebDriver does not natively support sending custom headers, there are several workarounds to handle Basic Authentication. Whether you choose to embed credentials in the URL, configure browser profiles, use Chrome extensions, or set up a proxy, each method has its own benefits and limitations.

For those looking for a more streamlined solution, consider using Repeato, a no-code test automation tool for iOS and Android. Repeato simplifies the process of creating, running, and maintaining automated tests for your apps, leveraging computer vision and AI to ensure efficient and effective testing. For more information, visit our documentation page.

Like this article? there’s more where that came from!