Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save darrenjrobinson/4200a28226454b61685891848119da99 to your computer and use it in GitHub Desktop.
Save darrenjrobinson/4200a28226454b61685891848119da99 to your computer and use it in GitHub Desktop.
Decoding Azure AD Access Tokens with Python and PyJWT 2.4.x Associated blogpost https://blog.darrenjrobinson.com/decoding-azure-ad-access-tokens-with-python/
import msal
import jwt
import json
import sys
import requests
from datetime import datetime
global accessToken
global requestHeaders
global tokenExpiry
accessToken = None
requestHeaders = None
tokenExpiry = None
graphURI = 'https://graph.microsoft.com'
tenantID = 'your AzureAD Tenant ID'
authority = 'https://login.microsoftonline.com/' + tenantID
clientID = 'client ID of your AAD Registered App'
scope = ['https://graph.microsoft.com/.default']
thumbprint = 'CertThumbprint'
certfile = '.\\path to\\PEM certfile.pem'
queryUser = "userx@yourTenant.onmicrosoft.com"
def msal_certificate_auth(clientID, scope, authority, thumbprint, certfile):
app = msal.ConfidentialClientApplication(clientID, authority=authority, client_credential={"thumbprint": thumbprint, "private_key": open(certfile).read()})
result = app.acquire_token_for_client(scopes=scope)
return result
def msgraph_request(resource, requestHeaders):
# Request
results = requests.get(resource, headers=requestHeaders).json()
return results
def msal_jwt_expiry(accessToken):
alg = jwt.get_unverified_header(accessToken['access_token'])['alg']
decodedAccessToken = jwt.decode(accessToken['access_token'], algorithms=[alg], options={"verify_signature": False})
accessTokenFormatted = json.dumps(decodedAccessToken, indent=2)
# Token Expiry
tokenExpiry = datetime.fromtimestamp(int(decodedAccessToken['exp']))
print("Token Expires at: " + str(tokenExpiry))
return tokenExpiry
# Auth
try:
if not accessToken:
try:
# Get a new Access Token using Client Credentials Flow and a Self Signed Certificate
accessToken = msal_certificate_auth(clientID, scope, authority, thumbprint, certfile)
requestHeaders = {
'Authorization': 'Bearer ' + accessToken['access_token']}
except Exception as err:
print('Error acquiring authorization token. Check your tenantID, clientID and certficate thumbprint.')
print(err)
if accessToken:
# Example of checking token expiry time to expire in the next 10 minutes
alg = jwt.get_unverified_header(accessToken['access_token'])['alg']
decodedAccessToken = jwt.decode(accessToken['access_token'], algorithms=[alg], options={"verify_signature": False})
accessTokenFormatted = json.dumps(decodedAccessToken, indent=2)
print("Decoded Access Token")
print(accessTokenFormatted)
# Token Expiry
tokenExpiry = datetime.utcfromtimestamp(decodedAccessToken["exp"])
print('Token Expiry: ' + str(tokenExpiry))
now = datetime.utcnow()
time_to_expiry = tokenExpiry - now
if time_to_expiry.seconds < 600:
print("Access Token Expiring Soon. Renewing Access Token.")
accessToken = msal_certificate_auth(clientID, scope, authority, thumbprint, certfile)
requestHeaders = {'Authorization': 'Bearer ' + accessToken['access_token']}
else:
minutesToExpiry = time_to_expiry.seconds / 60
print("Access Token Expires in '" + str(minutesToExpiry) +" minutes'")
except Exception as err:
print(err)
# Query
if requestHeaders and accessToken:
queryResults = msgraph_request(graphURI + '/beta/users/'+queryUser,requestHeaders)
try:
print(json.dumps(queryResults, indent=2))
except Exception as err:
print(err)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment