Reputation: 712
I am developing an application where all the API's are protected by OAuth. I have received the access token from the client, but could not decode and validate the token.
I have JWK in the below format
{
"keys": [
{
"kty": "RSA",
"x5t#S256": "Some value",
"e": "Some Value",
"x5t": "Some Value",
"kid": "SIGNING_KEY",
"x5c": [
"Some Value"
],
"key_ops": [
"verify",
"encrypt"
],
"alg": "RS256",
"n": "Some Value"
}
]
}
How to decode the JWT token using above JWK in Python?
Upvotes: 10
Views: 26642
Reputation: 1381
I did a little bit of clean up on @jason's work:
import jwt
from typing import Dict, Any
def decode_jwt_token(token: str, auth_domain: str, audience: str) -> Dict[str, Any]:
jwks_url = f'https://{auth_domain}/.well-known/jwks.json'
jwks_client = jwt.PyJWKClient(jwks_url)
header = jwt.get_unverified_header(token)
key = jwks_client.get_signing_key(header["kid"]).key
decoded = jwt.decode(token, key, [header["alg"]], audience=audience)
return decoded
Upvotes: 4
Reputation: 1094
I know that this is long ago answered, but this may be useful to somebody.
If you are working against an OAuth provider that supports OpenID, you can use something like the following which does the following:
from os import environ
import json
import urllib.request
import jwt;
def get_jwks_url(issuer_url):
well_known_url = issuer_url + "/.well-known/openid-configuration"
with urllib.request.urlopen(well_known_url) as response:
well_known = json.load(response)
if not 'jwks_uri' in well_known:
raise Exception('jwks_uri not found in OpenID configuration')
return well_known['jwks_uri']
def decode_and_validate_token(token):
unvalidated = jwt.decode(token, options={"verify_signature": False})
jwks_url = get_jwks_url(unvalidated['iss'])
jwks_client = jwt.PyJWKClient(jwks_url)
header = jwt.get_unverified_header(token)
key = jwks_client.get_signing_key(header["kid"]).key
return jwt.decode(token, key, [header["alg"]])
token = "xxxyyyzzz"
decoded = decode_and_validate_token(token)
print(decoded)
Upvotes: 10
Reputation: 4358
Fast check of your jwt token https://jwt.io/
otherwise you can try this, but you should know the algorithm used to generate the token (e.g. : HS256) and the key used for signing the token) (e.g. :super_secretkey)
import jwt # pip install pyjwt[crypto] to install the package
jwt.decode(token, key='super_secretkey', algorithms=['HS256', ])
Update decode the JWT using JWK
import json
import jwt
#for JWKS that contain multiple JWK
public_keys = {}
for jwk in jwks['keys']:
kid = jwk['kid']
public_keys[kid] = jwt.algorithms.RSAAlgorithm.from_jwk(json.dumps(jwk))
kid = jwt.get_unverified_header(token)['kid']
key = public_keys[kid]
payload = jwt.decode(token, key=key, algorithms=['RS256'])
Upvotes: 25