I have set up an authorization server using AzureAD. For testing it I am currently applying an implicit flow and to get a token and id_token I use https://oidcdebugger.com/.
Now I am trying to figure out how to properly validate a the token on the resource server side.
I always get a jose.exceptions.JWTError: Signature verification failed
.
Can you help me find out what I am doing wrong?
I am really new to JWT validation and probably there is some obvious error somwhere.
As defined by the OIDC metadata endpoint at
https://login.microsoftonline.com/{tenant_id}/v2.0/.well-known/openid-configuration
keys
for signature validation can be found at
https://login.microsoftonline.com/{tenant_id}/discovery/v2.0/keys
.
The key ids on that endpoint match the kid
value in my token headers.
So, I am positive that those are my keys.
They look like this:
{
"kty": "RSA",
"use": "sig",
"kid": "<the-key-id>",
"x5t": "<the-key-id>",
"n": "<a-long-hash>",
"e": "AQAB",
"x5c": ["<a-long-hash-I-guess-thats-the-public-key"],
"issuer": "https://login.microsoftonline.com/<my-tenant-id>/v2.0"
}
In the answer of this post the key is constructed by hand using cryptography.x509
.
I tried the same but I had to change a few details to make it run.
I am .encode
ing the string and I have to pass an iterable to the decode
function.
import requests
from jose import jwt
from cryptography.x509 import load_pem_x509_certificate
from cryptography.hazmat.backends import default_backend
AZURE_TENANT_ID = '<my-tenant-id>'
AZURE_KEYS = requests.get(url='<my-jwks_url>').json()['keys']
PEMSTART = "-----BEGIN CERTIFICATE-----\n"
PEMEND = "\n-----END CERTIFICATE-----\n"
def decode(token: str, keys: list):
token_header = jwt.get_unverified_header(token=token)
x5t = token_header['x5t']
key = [d for d in keys if d['x5t'] == x5t][0]
mspubkey = key['x5c'][0]
cert_str = PEMSTART + mspubkey + PEMEND
cert_obj = load_pem_x509_certificate(cert_str.encode(), default_backend())
public_key = cert_obj.public_key()
return jwt.decode(
token=token,
subject='<my-subject>',
audience='<my-audience>',
issuer=f'https://sts.windows.net/{AZURE_TENANT_ID}/',
algorithms=['RS256'],
key=[public_key])