Get a Pentest and security assessment of your IT network.

Cyber Security

JWT Client Authentication

TL;DR

This guide shows you how to authenticate a client using Bearer JWTs and get an access token from an authorization server. This is common for machine-to-machine communication, APIs, and secure applications.

1. Understand the Basics

Before we start, let’s quickly cover some key concepts:

  • Client: The application requesting access to protected resources (e.g., your mobile app or server).
  • Authorization Server: Issues access tokens after verifying the client’s identity.
  • Resource Server: Hosts the protected resources that clients want to access.
  • JWT (JSON Web Token): A standard for securely transmitting information as a JSON object. It’s digitally signed, so it can be trusted.
  • Bearer Token: An access token used in an HTTP Authorization header.

2. Client Registration

First, you need to register your client with the authorization server. This usually involves providing details like:

  • Client ID (a unique identifier)
  • Client Secret (a confidential key – keep this safe!)
  • Redirect URIs (where the authorization server will send responses after authentication)

The registration process varies depending on the authorization server. Consult its documentation.

3. Creating a JWT Client Assertion

Your client needs to create a signed JWT to prove its identity. Here’s how:

  1. Header: Include information like the signing algorithm (e.g., HS256) and token type.
  2. Payload: Add claims about your client, such as:
    • iss (Issuer): Your client ID.
    • sub (Subject): A unique identifier for the request.
    • aud (Audience): The authorization server’s URL.
    • exp (Expiration Time): When the token expires.
  3. Signature: Sign the JWT using your client secret and the chosen algorithm.

Example (using Python with the PyJWT library):

import jwt
import datetime

client_id = "your_client_id"
client_secret = "your_client_secret"
audience = "https://authorization-server.example.com"

payload = {
    "iss": client_id,
    "sub": "unique_request",
    "aud": audience,
    "exp": datetime.datetime.utcnow() + datetime.timedelta(minutes=5)
}

encoded_jwt = jwt.encode(payload, client_secret, algorithm="HS256")
print(encoded_jwt)

4. Requesting an Access Token

Send a POST request to the authorization server’s token endpoint with the following:

  • Grant Type: Typically client_credentials for machine-to-machine authentication.
  • Assertion: The JWT client assertion you created in step 3.
  • Client ID & Secret: Your registered client credentials (some servers require these even with the assertion).

Example using curl:

curl -X POST 
  -H "Content-Type: application/x-www-form-urlencoded" 
  -d "grant_type=client_credentials&assertion=&client_id=&client_secret=" 
  https://authorization-server.example.com/token

5. Handling the Response

The authorization server will respond with a JSON object containing:

  • access_token: The access token you’ll use to access protected resources.
  • token_type: Usually Bearer.
  • expires_in: How long the token is valid (in seconds).

Store the access token securely.

6. Accessing Protected Resources

When making requests to the resource server, include the access token in the Authorization header:

Authorization: Bearer 

The resource server will validate the token before granting access.

7. Refreshing Tokens (Optional)

If your authorization server supports it, you can use a refresh token to obtain new access tokens without re-authenticating. The process is similar to requesting an initial access token but uses the refresh_token grant type.

Related posts
Cyber Security

Zip Codes & PII: Are They Personal Data?

Cyber Security

Zero-Day Vulnerabilities: User Defence Guide

Cyber Security

Zero Knowledge Voting with Trusted Server

Cyber Security

ZeroNet: 51% Attack Risks & Mitigation