We are facing a strange problem here, token from Azure AD is being decoded for some, while for some people it is not getting decoded because of which APIs are failing, a flask framework based app uses Azure AD authentication. Adding the code snippet to better understand
import json
from functools import wraps
from flask import request, _request_ctx_stack
from jose import jwt
from six.moves.urllib.request import urlopen
import logging
import os.path
CLIENT_ID = "client_id"
TENANT_ID = "tenant_id"
AUTHORITY = f"https://login.microsoftonline.com/{TENANT_ID}"
JWKS_URI = f"{AUTHORITY}/discovery/v2.0/keys"
#ISSUER = f"{AUTHORITY}/v2.0"
ISSUER = f"https://sts.windows.net/{TENANT_ID}/"
ALGORITHMS = ["RS256"]
AUDIENCE = f"https://{company_name}.onmicrosoft.com/{CLIENT_ID}"
def get_token_auth_header():
"""Obtains the Access Token from the Authorization Header"""
access_token = None
try:
header = request.headers.get('Authorization').split(' ')
if len(header) != 2:
return {"error": {"code": 11, 'error': 'Token not found'}}, 401
if header[0].lower() != "bearer":
return {"error": {"code": 11}, 'error': 'Authorization header must be Bearer'}, 401
access_token = header[1]
except:
return {"error": {"code": 11, 'error': 'Auth not found.'}}, 401
return access_token
def validate_access_token(f):
""" Validate the token.
- Errors
code: 11 - Token not allowed, something is wrong.
code: 89 - Token has expired.
"""
@wraps(f)
def decorated(*args, **kwargs):
payload = None
token = get_token_auth_header()
if not token:
return {"error": {"code": 10, 'error': 'Token missing'}}, 401
jsonurl = urlopen(JWKS_URI)
jwks = json.loads(jsonurl.read())
try:
unverified_header = jwt.get_unverified_header(token)
except:
return {"error": {"code": 11, 'error': 'Token not allowed'}}, 401
rsa_key = {}
for key in jwks["keys"]:
if key["kid"] == unverified_header["kid"]:
rsa_key = {
"kty": key["kty"],
"kid": key["kid"],
"use": key["use"],
"n": key["n"],
"e": key["e"]
}
if rsa_key:
try:
payload = jwt.decode(
token,
key=rsa_key,
algorithms=ALGORITHMS,
audience=AUDIENCE,
issuer=ISSUER
)
except Exception as e:
print('Exception', e)
return {"error": {"code": 11, 'error': "Unable to parse authentication due to {}".format(e)}}, 401
except jwt.ExpiredSignatureError:
return {"error": {"code": 89, 'error': "Token is expired"}}, 401
except jwt.JWTClaimsError:
return {"error": {"code": 11, 'error': "Incorrect claims"}}, 401
_request_ctx_stack.top.current_user = payload
return f(*args, **kwargs)
return {"error": {"code": 11, 'error': "Unable to find appropriate key"}}, 401
return decorated
could someone help the code used to decode is correct ?
Trying to understand if some atttribute is missing while decoding the token with the existing code as it works for some and does not work for some