Last active
November 14, 2024 04:16
-
-
Save theGOTOguy/a20c0c7663b87005dd33192c903434a0 to your computer and use it in GitHub Desktop.
Example using WireMock to get a JWT
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import requests | |
from urllib.parse import urlparse, parse_qs | |
from http.server import BaseHTTPRequestHandler, HTTPServer | |
import threading | |
import jwt | |
from jwt import PyJWKClient | |
# Configuration | |
client_id = 'your_client_id' | |
client_secret = 'your_client_secret' | |
redirect_uri = 'http://localhost:8080/callback' # Arbitrary, will not be used. | |
scopes = 'openid profile email' | |
authorization_url = "https://oauth.wiremockapi.cloud/oauth/authorize" | |
login_url = "https://oauth.wiremockapi.cloud/login" | |
token_url = "https://oauth.wiremockapi.cloud/oauth/token" | |
well_known_url = "https://oauth.wiremockapi.cloud/.well-known/jwks.json" | |
username = '[email protected]' | |
password = 'my_password' | |
audience = 'null' # I can't figure out how we're supposed to set this in the flow. Maybe not supported in Wiremock. | |
# Step 1: Capture Authorization Code | |
def get_authorization_code(): | |
# Open the authorization URL in a browser | |
params = { | |
'client_id': client_id, | |
'redirect_uri': redirect_uri, | |
'response_type': 'code', | |
'scope': scopes, | |
'state': 'random_state_string', | |
'email': username, | |
'password': password, | |
'nonce': '' | |
} | |
response = requests.post(login_url, data=params) | |
# The response will include the code in the URL. | |
# We skip the whole redirect part. | |
# Step 1: Parse the URL to extract the query string | |
parsed_url = urlparse(response.url) | |
# Step 2: Extract the query parameters | |
query_params = parse_qs(parsed_url.query) | |
# Step 3: Get the "code" parameter value | |
code = query_params.get("code", [None])[0] | |
if code: | |
print("Authorization code received: {}".format(code)) | |
return code | |
else: | |
raise Exception("Failed to obtain authorization code") | |
# Step 2: Exchange Authorization Code for Access Token | |
def get_access_token(auth_code): | |
data = { | |
'grant_type': 'authorization_code', | |
'client_id': client_id, | |
'client_secret': client_secret, | |
'code': auth_code, | |
'redirect_uri': redirect_uri | |
} | |
headers = {'Content-Type': 'application/x-www-form-urlencoded'} | |
response = requests.post(token_url, data=data, headers=headers) | |
if response.ok: | |
token_data = response.json() | |
print(token_data) | |
access_token = token_data.get('access_token') | |
my_jwt = token_data.get('id_token') | |
print("Access Token:", access_token) | |
print("JWT:", my_jwt) | |
jwks_client = PyJWKClient(well_known_url) | |
signing_key = jwks_client.get_signing_key_from_jwt(my_jwt) | |
print("Decoded JWT:", jwt.decode(my_jwt, signing_key.key, audience=audience, algorithms=["RS256"])) | |
return access_token | |
else: | |
raise Exception("Failed to get access token:", response.text) | |
# User Info. | |
# Step 3: Fetch User Info (Optional) | |
def fetch_user_info(access_token): | |
user_info_url = "https://oauth.wiremockapi.cloud/userinfo" | |
headers = {'Authorization': f'Bearer {access_token}'} | |
response = requests.get(user_info_url, headers=headers) | |
if response.ok: | |
print("User Info:", response.json()) | |
else: | |
print("Failed to get user info:", response.status_code, response.text) | |
# Run the flow | |
if __name__ == "__main__": | |
try: | |
# Get authorization code | |
auth_code = get_authorization_code() | |
if auth_code: | |
# Exchange code for token | |
token = get_access_token(auth_code) | |
# Get user info. | |
fetch_user_info(token) | |
except Exception as e: | |
print("Error:", e) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment