0

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

0 Answers0