Introduction
In our REST Assured series, we’ve explored topics like GPath Expressions, XML Path Testing, and JSON Path Testing, building a strong foundation for API testing. Now, we’ll dive into Basic Authentication, a common security mechanism for protecting API endpoints. This guide demonstrates how to implement Basic Authentication in REST Assured to test secured APIs, using clear examples and best practices. It’s designed for beginners and experienced developers, ensuring you can confidently handle authenticated requests.
Key Point: Basic Authentication in REST Assured allows you to send username and password credentials in API requests, enabling testing of protected endpoints securely and efficiently.
What is Basic Authentication?
Basic Authentication is an HTTP authentication scheme where credentials (username and password) are encoded in Base64 and sent in the Authorization
header of an HTTP request. The header format is:
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
Key characteristics:
- Simple: Easy to implement but requires HTTPS to secure credentials.
- Base64 Encoded: Credentials are not encrypted, only encoded.
- Common Use: Used in APIs requiring lightweight authentication.
REST Assured simplifies Basic Authentication with methods like auth().basic()
, handling the encoding and header setup automatically. We’ll use the public API https://httpbin.org/basic-auth/user/passwd
, which simulates Basic Authentication with the credentials user:passwd
, for our examples.
Setting Up for Basic Authentication Testing
To test Basic Authentication, we’ll set up a Maven project with REST Assured, JUnit, and Allure for reporting, consistent with previous posts in the series.
Here’s the pom.xml
, styled with your preferred Blogger format for XML syntax highlighting:
<project xmlns="http://maven.apache.org/POM/4.0.0">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>rest-assured-tests</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>11</java.version>
<allure.version>2.27.0</allure.version>
<aspectj.version>1.9.22</aspectj.version>
</properties>
<dependencies>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>5.4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest</artifactId>
<version>2.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-junit5</artifactId>
<version>${allure.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
<configuration>
<argLine>
-javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"</argLine>
</configuration>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-maven</artifactId>
<version>2.12.0</version>
<configuration>
<reportVersion>${allure.version}</reportVersion>
</configuration>
</plugin>
</plugins>
</build>
</project>
No additional setup is required for https://httpbin.org
, as it provides a reliable endpoint for testing Basic Authentication.
Implementing Basic Authentication in REST Assured
Let’s explore how to implement and test Basic Authentication using REST Assured in various scenarios.
Example 1: Basic Authentication with Valid Credentials
Test an API endpoint using valid Basic Authentication credentials.
import io.qameta.allure.Description;
import io.qameta.allure.Feature;
import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
@Feature("Basic Authentication Testing")
public class BasicAuthValidTest {
@Test
@Description("Test Basic Authentication with valid credentials")
public void testValidBasicAuth() {
RestAssured.baseURI = "https://httpbin.org";
given()
.auth().basic("user", "passwd")
.log().all()
.when()
.get("/basic-auth/user/passwd")
.then()
.statusCode(200)
.body("authenticated", equalTo(true))
.body("user", equalTo("user"));
}
}
Explanation:
auth().basic("user", "passwd")
: Sets Basic Authentication with the usernameuser
and passwordpasswd
.statusCode(200)
: Verifies successful authentication.body("authenticated", equalTo(true))
: Checks the response confirms authentication.log().all()
: Logs request and response for debugging.
Important: Always use HTTPS with Basic Authentication to protect credentials, as Base64 encoding is not secure over HTTP.
Example 2: Handling Invalid Credentials
Test an API endpoint with invalid credentials to verify error handling.
import io.qameta.allure.Description;
import io.qameta.allure.Feature;
import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
@Feature("Basic Authentication Testing")
public class BasicAuthInvalidTest {
@Test
@Description("Test Basic Authentication with invalid credentials")
public void testInvalidBasicAuth() {
RestAssured.baseURI = "https://httpbin.org";
given()
.auth().basic("wronguser", "wrongpass")
.log().ifValidationFails()
.when()
.get("/basic-auth/user/passwd")
.then()
.statusCode(401)
.body("error", containsString("Unauthorized"));
}
}
Explanation:
auth().basic("wronguser", "wrongpass")
: Uses incorrect credentials.statusCode(401)
: Expects an Unauthorized response.log().ifValidationFails()
: Logs details only if the test fails, reducing console clutter.
Example 3: Preemptive Basic Authentication
Use preemptive Basic Authentication to send credentials proactively, avoiding a challenge-response cycle.
import io.qameta.allure.Description;
import io.qameta.allure.Feature;
import io.restassured.RestAssured;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
@Feature("Basic Authentication Testing")
public class PreemptiveBasicAuthTest {
@Test
@Description("Test preemptive Basic Authentication")
public void testPreemptiveBasicAuth() {
RestAssured.baseURI = "https://httpbin.org";
given()
.auth().preemptive().basic("user", "passwd")
.log().all()
.when()
.get("/basic-auth/user/passwd")
.then()
.statusCode(200)
.body("authenticated", equalTo(true))
.body("user", equalTo("user"));
}
}
Explanation:
auth().preemptive().basic()
: Sends theAuthorization
header proactively, improving performance for servers expecting immediate credentials.- The response is validated similarly to Example 1.
Pro Tip: Use preemptive authentication for APIs that require credentials in the initial request to reduce latency and avoid unnecessary server challenges.
Example 4: Basic Authentication with Response Specification
Combine Basic Authentication with a ResponseSpecification for reusable validation.
import io.qameta.allure.Description;
import io.qameta.allure.Feature;
import io.restassured.RestAssured;
import io.restassured.builder.ResponseSpecBuilder;
import io.restassured.specification.ResponseSpecification;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
@Feature("Basic Authentication Testing")
public class BasicAuthWithSpecTest {
private ResponseSpecification authSuccessSpec;
@BeforeEach
public void setup() {
authSuccessSpec = new ResponseSpecBuilder()
.expectStatusCode(200)
.expectContentType("application/json")
.expectBody("authenticated", equalTo(true))
.expectBody("user", equalTo("user"))
.build();
}
@Test
@Description("Test Basic Authentication with Response Specification")
public void testBasicAuthWithSpec() {
RestAssured.baseURI = "https://httpbin.org";
given()
.auth().basic("user", "passwd")
.log().all()
.when()
.get("/basic-auth/user/passwd")
.then()
.spec(authSuccessSpec);
}
}
Explanation:
authSuccessSpec
: Defines a specification for successful authentication responses.spec(authSuccessSpec)
: Applies the specification to validate the response.
Integrating with Allure Reporting
Document Basic Authentication tests with Allure, attaching request and response details.
import io.qameta.allure.Allure;
import io.qameta.allure.Description;
import io.qameta.allure.Feature;
import io.restassured.RestAssured;
import io.restassured.response.Response;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
@Feature("Basic Authentication Testing")
public class AllureBasicAuthTest {
@Test
@Description("Test Basic Authentication with Allure reporting")
public void testBasicAuthWithAllure() {
RestAssured.baseURI = "https://httpbin.org";
Response response = given()
.auth().basic("user", "passwd")
.log().all()
.when()
.get("/basic-auth/user/passwd")
.then()
.statusCode(200)
.body("authenticated", equalTo(true))
.extract().response();
Allure.addAttachment("Response Body", "application/json", response.asString(), ".json");
}
}
Explanation:
Allure.addAttachment
: Attaches the response body to the Allure report.- Run
mvn clean test
andmvn allure:serve
to view the report.
Integrating with CI/CD
Add Basic Authentication tests to a GitHub Actions pipeline for automation.
Create or update .github/workflows/ci.yml
:
name: REST Assured CI Pipeline
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up JDK 11
uses: actions/setup-java@v4
with:
java-version: '11'
distribution: 'temurin'
- name: Cache Maven dependencies
uses: actions/cache@v4
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-maven-
- name: Run tests
run: mvn clean test
- name: Generate Allure report
run: mvn allure:report
- name: Upload Allure results
if: always()
uses: actions/upload-artifact@v4
with:
name: allure-results
path: target/allure-results
- name: Publish Allure report
if: always()
uses: simple-elf/allure-report-action@v1.7
with:
allure_results: target/allure-results
gh_pages: gh-pages
allure_report: allure-report
- name: Deploy report to GitHub Pages
if: always()
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: allure-report
Explanation:
- Runs Basic Authentication tests with
mvn clean test
. - Publishes Allure reports to GitHub Pages for visibility.
Tips for Beginners
- Secure Credentials: Store credentials in environment variables or configuration files, not hardcoded in tests.
- Use HTTPS: Ensure the API uses HTTPS to protect Base64-encoded credentials.
- Test Error Cases: Validate behavior for invalid or missing credentials (e.g., 401 Unauthorized).
- Log Selectively: Use
log().ifValidationFails()
to debug authentication failures efficiently.
Troubleshooting Tip: If authentication fails, enablelog().all()
to inspect theAuthorization
header and verify credentials against the API documentation.
What’s Next?
This post enhances our REST Assured series by introducing Basic Authentication, a key skill for testing secured APIs. To continue your learning, consider exploring:
- OAuth 2.0 Authentication: Testing APIs with token-based authentication.
- API Key Authentication: Handling APIs that use API keys in headers or query parameters.
- End-to-End Testing: Combining REST Assured with Selenium for UI and API testing.