This guide will help you generate a Client Assertion for authenticating with an OAuth service. Follow the steps below, including creating public/private key pairs and using Python to encode a JWT.
Step 1: Generate RSA Public and Private Keys
Before creating the Client Assertion, you need an RSA key pair:
-
Generate the Private Key:
Use the following OpenSSL command to create a private key file (private_key.pem):openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048 -
Extract the Public Key:
Use the private key to extract the corresponding public key (public_key.pem):openssl rsa -pubout -in private_key.pem -out public_key.pem -
Save the Keys Securely:
- Private Key: Keep this secure and never expose it publicly.
- Public Key: Share this with the service or API provider for validation purposes.
Step 2: Set Up Your OAuth App on the Dashboard
- Create an OAuth application on the provider’s dashboard.
- Upon creation, you’ll receive the following details:
- Client ID: A unique identifier for your application.
- Key ID (
key_id): Identifies the RSA key pair you’re using.
Step 3: Python Code for Generating the JWT
Below is a Python script that generates the Client Assertion (JWT). It uses the PyJWT library to encode the JWT with your private key.
Python Script:
import time
import uuid
import jwt # Install this with: pip install pyjwt
# Replace this with the key_id provided by the service
key_id = "key-8ef00462-37a2-4caf-9b4f-ea1d1f872539"
# Load the RSA private key from the generated file
with open("./private_key.pem", "r") as key_file:
private_key = key_file.read()
# Define claims for the JWT
claims = {
'iss': 'tAcCQczwE3eJIl4vXKq1dkJl45mmWqu4mqFa7td5x1g', # Replace with your client_id
'sub': 'tAcCQczwE3eJIl4vXKq1dkJl45mmWqu4mqFa7td5x1g', # Same as client_id
'aud': 'http://localhost:8000/oauth/token/', # Replace with the API's token endpoint
'exp': int(time.time()) + 300, # Token expires in 5 minutes
'iat': int(time.time()), # Token issued at the current time
'jti': str(uuid.uuid4()) # Unique identifier for the assertion
}
# Encode the JWT
assertion = jwt.encode(
claims,
private_key,
algorithm='RS256',
headers={'kid': key_id} # Specify the key_id
)
# Print the generated Client Assertion
print(assertion)
Key Components of the Script:
-
key_id:
This is the unique identifier for your RSA key. It is provided when setting up your OAuth app. -
private_key.pem:
The private key file used to sign the JWT. -
JWT Claims:
iss: The issuer, which should be yourclient_id.sub: The subject, also yourclient_id.aud: The audience, usually the token endpoint URL of the service.exp: The expiration timestamp (in Unix format).iat: The issued-at timestamp (in Unix format).jti: A unique identifier for the JWT to prevent replay attacks.
-
JWT Header:
- Includes the
alg(algorithm,RS256) andkid(key ID).
- Includes the
Step 4: Using the Client Assertion
After running the script, the generated token will be printed to the console. Use this token in your OAuth request to the API’s token endpoint.
For example:
POST /oauth/token/ HTTP/1.1
Host: api.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
&client_assertion=<YOUR_GENERATED_ASSERTION>
Replace <YOUR_GENERATED_ASSERTION> with the JWT from the Python script.
Notes:
- Always use a secure method to store your private key.
- Ensure your timestamps (
expandiat) are accurate and in Unix time format. - Validate the
audvalue with your service provider to avoid errors.
