Network Interception with Selenium WebDriver BiDi

Published on December 8, 2024

Automate Basic Authentication with BiDi Network Domain

Thumbnail for article: Network Interception with Selenium WebDriver BiDi
Article agenda

Introduction

In today’s web automation landscape, handling network-level interactions is becoming increasingly crucial, especially when dealing with authentication protocols. HTTP Basic Authentication, while simple, presents challenges when automating workflows that require dynamic credential management. Selenium WebDriver’s Bi-Directional (BiDi) APIs offer a powerful solution by enabling interception and manipulation of network requests in real time. In this article, we’ll explore how to use these capabilities to automate HTTP Basic Authentication, leveraging a step-by-step Java implementation to demonstrate the process.

Basic Authentication

Basic Authentication is a widely used method to protect online resources. When we send a request to the server, it travels through the browser, which then forwards it to the server. The server responds with a request for credentials, typically displaying a dialog box where we can input a username and password. Once we provide the correct credentials, access to the requested resources is granted. It’s a simple and straightforward process.

AUT: http://httpbin.org/basic-auth/foo/bar

We’ll use AUT: http://httpbin.org/basic-auth/foo/bar to test basic auth. The page shows us a small prompt - a dialogue box asking for the username and password. When we enter username “foo” and password “bar”, we get correctly authenticated.

Open browser DevTools Network tab to confirm Basic Auth was sent

Let’s check what happens in the background, in the context of response and request headers. We are especially interested in the Request Headers part, where it shows Basic . This indicates that the Basic Auth information was sent.

It’s time to code this up. We’ll write a Java program which demonstrates how to use Selenium WebDriver’s BiDi (Bi-Directional) capabilities to handle HTTP Basic Authentication when navigating to a webpage. Let’s walk through the code step-by-step:

1. Import Statements

import org.openqa.selenium.By;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
  • org.openqa.selenium.bidi imports: These are for the BiDi APIs, enabling communication between the browser and Selenium in both directions.
  • FirefoxDriver and FirefoxOptions: Used for configuring and starting the Firefox browser.
  • Network: A BiDi module that allows intercepting network requests and responses, including handling authentication.

2. Declare Class and Fields

static protected WebDriver driver;
static protected Network network;
  • WebDriver: The interface to control the browser.
  • Network: The module that handles BiDi network features.

3. Main Method Overview

public static void main(String[] args) {

The entry point sets up the browser, handles authentication using the BiDi APIs, and verifies the result.

4. Configure Firefox with BiDi Support

var options = new FirefoxOptions();
options.enableBiDi();
driver = new FirefoxDriver(options);
network = new Network(driver);
  • enableBiDi(): Enables BiDi capabilities for Firefox.
  • FirefoxDriver with options: Launches the browser with the specified options.
  • Network: Initializes the BiDi Network module for the driver.

5. Add an Interceptor for Basic Authentication

network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED));
  • addIntercept: Sets up an interceptor to handle authentication requests.
  • InterceptPhase.AUTH_REQUIRED: Specifies that the interception occurs during the authentication phase of network requests.

6. Handle Authentication Prompt

network.onAuthRequired(responseDetails -> network.continueWithAuth(
responseDetails.getRequest().getRequestId(),
new UsernameAndPassword("foo", "bar")
));
  • onAuthRequired: Listener for authentication prompts. It executes when the AUTH_REQUIRED phase is triggered.
  • responseDetails.getRequest().getRequestId(): Retrieves the unique ID for the network request that requires authentication.
  • continueWithAuth: Supplies the credentials (foo and bar) to handle the authentication.

7. Access the Target URL

driver.get("http://httpbin.org/basic-auth/foo/bar");
  • Navigates to a test webpage that requires HTTP Basic Authentication.

8. Verify Authentication Success

var text = driver.findElement(By.tagName("body"));
boolean auth = text.getText().contains("authenticated");
assert (auth);
System.out.println(auth);
  • findElement(By.tagName("body")): Retrieves the body content of the webpage.
  • getText().contains("authenticated"): Checks if the body contains the string "authenticated," confirming successful login.
  • assert(auth): Validates the authentication result and prints the result to the console.

9. Clean Up

network.close();
driver.quit();
  • network.close(): Closes the BiDi Network module.
  • driver.quit(): Closes the browser and ends the WebDriver session.

Key Features

  • BiDi API Usage: The program demonstrates intercepting network phases and dynamically responding to authentication prompts.
  • HTTP Basic Authentication: The program handles username/password-based HTTP authentication programmatically without manual input.
  • Validation: Asserts the authentication success to ensure program correctness.

Execution Flow

  1. Browser setup with BiDi capabilities.
  2. Set up a network interceptor for AUTH_REQUIRED events.
  3. Handle authentication prompts by providing credentials.
  4. Navigate to the target URL.
  5. Verify the response content to ensure successful authentication.
  6. Clean up resources.

Full Code

BasicAuth.java:

import org.openqa.selenium.By;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

public class BasicAuth {

static protected WebDriver driver;
static protected Network network;

public static void main(String[] args) {

var options = new FirefoxOptions();
options.enableBiDi();
driver = new FirefoxDriver(options);
network = new Network(driver);

network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED));
network.onAuthRequired(responseDetails -> network.continueWithAuth(responseDetails.getRequest().getRequestId(),
new UsernameAndPassword("foo", "bar")));

driver.get("http://httpbin.org/basic-auth/foo/bar");

var body = driver.findElement(By.tagName("body"));

boolean auth = body.getText().contains("authenticated");
assert (auth);
System.out.println(auth);

network.close();
driver.quit();
};
}
Basic Auth code execution demo: https://youtu.be/8SjpFnREKsA

Summary

This article delved into automating HTTP Basic Authentication using Selenium WebDriver’s BiDi capabilities. By intercepting the authentication phase of network requests, we dynamically handled credentials and verified the successful login programmatically. The example demonstrated browser setup, network interception, credential management, and validation, showcasing a practical approach to overcoming automation challenges with HTTP Basic Authentication. These techniques highlight the flexibility and power of Selenium BiDi APIs for advanced automation scenarios.

𝓗𝒶𝓅𝓅𝓎 𝓉𝓮𝓈𝓉𝒾𝓃𝓰 𝒶𝓃𝒹 𝒹𝓮𝒷𝓊𝓰𝓰𝒾𝓃𝓰!

I welcome any comments and contributions to the subject. Connect with me on LinkedIn, X , GitHub, or Insta. Check out my website.

If you find this post useful, please consider buying me a coffee.