Esempio n. 1
0
def decode_access_token(auth_header, CLIENT_ID):
    # Get discovery document
    try:
        token = auth_header.split(" ")[1].strip()
        decoded_token = jt.decode(token.decode('utf-8'), verify=False)
        alg = jwt.get_unverified_header(token)['alg']
        kid = jwt.get_unverified_header(token)['kid']

        # Validate the token values
        validated = token_validation(decoded_token, alg, kid, CLIENT_ID)
        
        # Validate keys
        for key in DIRTY_KEYS:
            #Validate the key
            try:
                KEYS.append(jws.verify(token, key, algorithms=[alg]))
            except JWSError:
                return JWSError

        if validated == True:
            # Verify email address is held
            email = ""
            if 'email' in decoded_token:
                # Id token 
                email = decoded_token['email']
            else:
                email = get_user_data(get_discovery_document(decoded_token)['userinfo_endpoint'], auth_header)['email']
            return get_gravitar(email)
        else:
            return validated
    except:
        return {'Error' : 'Could not decode Token'}

    # Default Error
    return {'Error' : 'Unexpected error occurred'}
Esempio n. 2
0
def is_valid(token):
    if not token: return False

    try:
        unverified_header = jwt.get_unverified_header(token)
    except jwt.JWTError, e:
        raise APIError("invalid_header", "Invalid header: %s" % e, 401)
Esempio n. 3
0
    def _decode_claims(self, token):
        """Decode the claims in a token."""
        from jose import jwt, exceptions as jose_exceptions
        try:
            header = jwt.get_unverified_header(token)
        except jose_exceptions.JWTError as err:
            raise ValueError(str(err)) from None
        kid = header.get('kid')

        if kid is None:
            raise ValueError("No kid in header")

        # Locate the key for this kid
        key = None
        for key_dict in self.jwt_keyset['keys']:
            if key_dict['kid'] == kid:
                key = key_dict
                break
        if not key:
            raise ValueError(
                "Unable to locate kid ({}) in keyset".format(kid))

        try:
            return jwt.decode(
                token, key, audience=self.cognito_client_id, options={
                    'verify_exp': False,
                })
        except jose_exceptions.JWTError as err:
            raise ValueError(str(err)) from None
Esempio n. 4
0
def verify_id_token(id_token):
    keys = GoogleKeys.fetch_public_keys()

    headers = jwt.get_unverified_header(id_token)
    #print '--- headers ---'
    #print headers
    #print '--- claims ---'
    claims = json.loads(jwt.get_unverified_claims(id_token))
    #print claims

    error_message = None
    if not headers.get('kid'):
        error_message = 'Firebase Auth ID token has no "kid" claim'
    elif headers.get('alg') != ALGORITHM:
        error_message = 'Firebase Auth ID token has incorrect algorithm'
    elif claims.get('aud') != PROJECT_ID:
        error_message = 'Firebase Auth ID token has incorrect "aud" claim'
    elif claims.get('iss') != 'https://securetoken.google.com/' + PROJECT_ID:
        error_message = 'Firebase Auth ID token has incorrect "iss" claim'
    elif not claims.get('sub') or len(claims['sub']) > 128:
        error_message = 'Firebase Auth ID token has invalid "sub" claim'

    if error_message:
        raise Exception(error_message)

    key = cert_to_public_rsa_key(keys[headers['kid']])

    result = jwt.decode(id_token, key, algorithms=[ALGORITHM], audience=PROJECT_ID)
    #print '--- verification ---'
    #print result

    return result
Esempio n. 5
0
def process_jwt_token():
    authorization = request.cookies.get(
        'jwt',
        request.headers.get(
            'Authorization',
            None
        ))

    if authorization is None:
        response = make_response('Not JWT token')
        response.status_code = 401
        return response

    msg = ""
    ss = authorization.split(' ', 1)
    if len(ss) != 2:
        msg = "Unauthorized"
    else:
        type, token = ss[0], ss[1]
        if type.lower() == 'bearer':
            try:
                headers = jwt.get_unverified_header(token)
                payload = jwt.decode(
                    token,
                    app.config['oauth'].get('jwt_key'),
                    algorithms=[headers['alg']],
                    audience=app.config['oauth']['organization'],
                    issuer='itsyouonline')
                # case JWT is for an organization
                if 'globalid' in payload and payload['globalid'] == app.config['oauth'].get('organization'):
                    return

                # case JWT is for a user
                if 'scope' in payload and 'user:memberof:%s' % app.config[
                        'oauth'].get('organization') in payload['scope']:
                    return

                msg = 'Unauthorized'
            except exceptions.ExpiredSignatureError as e:
                msg = 'Your JWT has expired'

            except exceptions.JOSEError as e:
                msg = 'JWT Error: %s' % str(e)

            except Exception as e:
                msg = 'Unexpected error : %s' % str(e)

        else:
            msg = 'Your JWT is invalid'

    logger.error(msg)
    response = make_response(msg)
    response.status_code = 401
    return response
Esempio n. 6
0
    def _get_user_info(self, request):
        access_token = self._get_token_auth_header(request)
        id_token = request.META.get("HTTP_IDTOKEN")

        # JWT Validator
        # Per https://auth0.com/docs/quickstart/backend/python/01-authorization#create-the-jwt-validation-decorator

        unverified_header = jwt.get_unverified_header(id_token)

        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 not rsa_key:
            raise AuthError({"code": "rsa_key",
                            "description": "rsa_key is empty"}, 401)

        try:
            user_info = jwt.decode(
                id_token,
                rsa_key,
                algorithms=['RS256'],
                audience=AUTH0_CLIENTID,
                access_token=access_token,
                issuer="https://"+AUTH0_DOMAIN+"/"
            )

            return user_info
        except jwt.ExpiredSignatureError:
            raise AuthError("Token is expired")
        except jwt.JWTClaimsError:
            raise AuthError("Incorrect claims: please check the audience and issuer")
        except Exception:
            raise AuthError("Invalid header: Unable to parse authentication")
Esempio n. 7
0
def verify_decode_jwt(token):
    jsonurl = urlopen(f"https://{AUTH0_DOMAIN}/.well-known/jwks.json")
    jwks = json.loads(jsonurl.read())

    unverified_header = jwt.get_unverified_header(token)

    rsa_key = {}
    if "kid" not in unverified_header:
        raise AuthError(
            {
                "code": "invalid_header",
                "message": "Authorization malformed"
            }, 401)

    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,
                                 rsa_key,
                                 algorithms=ALGORITHMS,
                                 audience=API_AUDIENCE,
                                 issuer="https://" + AUTH0_DOMAIN + "/")
            return payload

        except jwt.ExpiredSignatureError:
            raise AuthError(
                {
                    "code": "token_expired",
                    "message": "Token expired"
                }, 401)

        except jwt.JWTClaimsError:
            raise AuthError(
                {
                    "code":
                    "invalid_claims",
                    "message":
                    "Incorrect claims. Please, check the audience and issuer."
                },
                401,
            )

        except Exception:
            raise AuthError(
                {
                    "code": "invalid_header",
                    "message": "Unable to parse authentication token"
                }, 400)
    raise AuthError(
        {
            "code": "invalid_header",
            "message": "Unable to find the appropriate key."
        }, 400)
Esempio n. 8
0
def verify_decode_jwt(token):
    # Get public key from Auth0
    jsonurl = urlopen(f'https://{AUTH0_DOMAIN}/.well-known/jwks.json')
    jwks = json.loads(jsonurl.read())

    # Get data in header
    unverified_header = jwt.get_unverified_header(token)

    # Check validity of Auth0 token
    if 'kid' not in unverified_header:
        raise AuthError(
            {
                'code': 'invalid_header',
                'description': 'Authorization malformed.'
            }, 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']
            }

    # Verify the token
    if rsa_key:
        try:
            # Validate JWT using key
            payload = jwt.decode(token,
                                 rsa_key,
                                 algorithms=ALGORITHMS,
                                 audience=API_AUDIENCE,
                                 issuer='https://' + AUTH0_DOMAIN + '/')

            return payload

        except jwt.ExpiredSignatureError:
            raise AuthError(
                {
                    'code': 'token_expired',
                    'description': 'Token expired.'
                }, 401)

        except jwt.JWTClaimsError:
            raise AuthError(
                {
                    'code':
                    'invalid_claims',
                    'description':
                    'Incorrect claims. Please, check the audience and issuer.'
                }, 401)
        except Exception:
            raise AuthError(
                {
                    'code': 'invalid_header',
                    'description': 'Unable to parse authentication token.'
                }, 400)
    raise AuthError(
        {
            'code': 'invalid_header',
            'description': 'Unable to find the appropriate key.'
        }, 400)
Esempio n. 9
0
    def _get_user_info(self, access_token, id_token):
        """
        Extracts the user info payload from the Id Token.

        Example return value:

        {
            "at_hash": "<HASH>",
            "aud": "<HASH>",
            "email_verified": true,
            "email": "*****@*****.**",
            "exp": 1551259495,
            "family_name": "Surname",
            "given_name": "Firstname",
            "https://sso.mozilla.com/claim/groups": [
                "all_scm_level_1",
                "all_scm_level_2",
                "all_scm_level_3",
                # ...
            ],
            "iat": 1550654695,
            "iss": "https://auth.mozilla.auth0.com/",
            "name": "Firstname Surname",
            "nickname": "Firstname Surname",
            "nonce": "<HASH>",
            "picture": "<GRAVATAR_URL>",
            "sub": "ad|Mozilla-LDAP|fsurname",
            "updated_at": "2019-02-20T09:24:55.449Z",
        }
        """

        # JWT Validator
        # Per https://auth0.com/docs/quickstart/backend/python/01-authorization#create-the-jwt-validation-decorator

        try:
            unverified_header = jwt.get_unverified_header(id_token)
        except jwt.JWTError:
            raise AuthError('Unable to decode the Id token header')

        if 'kid' not in unverified_header:
            raise AuthError('Id token header missing RSA key ID')

        rsa_key = None
        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"]
                }
                break

        if not rsa_key:
            raise AuthError('Id token using unrecognised RSA key ID')

        try:
            # https://python-jose.readthedocs.io/en/latest/jwt/api.html#jose.jwt.decode
            user_info = jwt.decode(id_token,
                                   rsa_key,
                                   algorithms=['RS256'],
                                   audience=AUTH0_CLIENTID,
                                   access_token=access_token,
                                   issuer="https://" + AUTH0_DOMAIN + "/")
            return user_info
        except jwt.ExpiredSignatureError:
            raise AuthError('Id token is expired')
        except jwt.JWTClaimsError:
            raise AuthError(
                "Incorrect claims: please check the audience and issuer")
        except jwt.JWTError:
            raise AuthError("Invalid header: Unable to parse authentication")
Esempio n. 10
0
def verify_decode_jwt(token):
    '''
        @INPUTS
            token: a json web token (string)

        it should be an Auth0 token with key id (kid)
        it should verify the token using Auth0 /.well-known/jwks.json
        it should decode the payload from the token
        it should validate the claims
        return the decoded payload
    '''
    jsonurl = urlopen(f'https://{AUTH0_DOMAIN}/.well-known/jwks.json')
    jwks = json.loads(jsonurl.read())
    unverified_header = jwt.get_unverified_header(token)
    rsa_key = {}
    if 'kid' not in unverified_header:
        raise AuthError(
            {
                'code': 'invalid_header',
                'description': 'Authorization malformed.'
            }, 401)

    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,
                                 rsa_key,
                                 algorithms=ALGORITHMS,
                                 audience=API_AUDIENCE,
                                 issuer='https://' + AUTH0_DOMAIN + '/')

            return payload

        except jwt.ExpiredSignatureError:
            raise AuthError(
                {
                    'code': 'token_expired',
                    'description': 'Token expired.'
                }, 401)

        except jwt.JWTClaimsError:
            raise AuthError(
                {
                    'code':
                    'invalid_claims',
                    'description':
                    'Incorrect claims. Please, check the audience and issuer.'
                }, 401)
        except Exception:
            raise AuthError(
                {
                    'code': 'invalid_header',
                    'description': 'Unable to parse authentication token.'
                }, 401)
    raise AuthError(
        {
            'code': 'invalid_header',
            'description': 'Unable to find the appropriate key.'
        }, 401)
    def decorated(*args, **kwargs):
        token = get_token_auth_header()
        jsonurl = urlopen("https://" + AUTH0_DOMAIN + "/.well-known/jwks.json")
        jwks = json.loads(jsonurl.read())
        try:
            unverified_header = jwt.get_unverified_header(token)
        except jwt.JWTError:
            raise AuthError(
                {
                    "code":
                    "invalid_header1",
                    "description":
                    "Invalid header. "
                    "Use an RS256 signed JWT Access Token"
                }, 401)
        if unverified_header["alg"] == "HS256":
            raise AuthError(
                {
                    "code":
                    "invalid_header2",
                    "description":
                    "Invalid header. "
                    "Use an RS256 signed JWT Access Token"
                }, 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,
                                     rsa_key,
                                     algorithms=ALGORITHMS,
                                     audience=API_IDENTIFIER,
                                     issuer="https://" + AUTH0_DOMAIN + "/")
            except jwt.ExpiredSignatureError:
                raise AuthError(
                    {
                        "code": "token_expired",
                        "description": "token is expired"
                    }, 401)
            except jwt.JWTClaimsError:
                raise AuthError(
                    {
                        "code":
                        "invalid_claims",
                        "description":
                        "incorrect claims,"
                        " please check the audience and issuer"
                    }, 401)
            except Exception:
                raise AuthError(
                    {
                        "code": "invalid_header",
                        "description": "Unable to parse authentication"
                        " token."
                    }, 401)

            _request_ctx_stack.top.current_user = payload
            return f(*args, **kwargs)
        raise AuthError(
            {
                "code": "invalid_header",
                "description": "Unable to find appropriate key"
            }, 401)
Esempio n. 12
0
    def validate_token(self, token):
        """
        Validate token
        (Taken from
        http://openid.net/specs/openid-connect-core-1_0.html#TokenResponseValidation)
        """
        """ Step 1
            If encrypted, decrypt it using the keys and algorithms specified
            in the meta_data

            If encryption was negotiated but not provided, REJECT

            Skipping Okta has not implemented encrypted JWT
        """

        try:
            decoded_token = jwt_python.decode(token, verify=False)
        except jwt_python.exceptions.DecodeError:
            raise InvalidToken("Unable to decode jwt")

        dirty_alg = jwt.get_unverified_header(token)["alg"]
        dirty_kid = jwt.get_unverified_header(token)["kid"]

        key = self._jwks(dirty_kid)
        if key:
            # Validate the key using jose-jws
            try:
                jws.verify(token, key, algorithms=[dirty_alg])
            except (JWTError, JWSError) as err:
                raise InvalidTokenSignature("Invalid token signature") from err
        else:
            raise InvalidTokenSignature("Unable to fetch public signing key")
        """ Step 2
            Issuer Identifier for the OpenID Provider (which is typically
            obtained during Discovery) MUST exactly match the value of the
            iss (issuer) Claim.
            Redundant, since we will validate in Step 3, the "iss" claim matches
            host we requested the token from
        """

        if decoded_token["iss"] != self.config.issuer:
            """Step 3
            Client MUST validate:
                aud (audience) contains the same `client_id` registered
                iss (issuer) identified as the aud (audience)
                aud (audience) Claim MAY contain an array with more than one
                element (Currently NOT IMPLEMENTED by Okta)
            The ID Token MUST be rejected if the ID Token does not list the
            Client as a valid audience, or if it contains additional audiences
            not trusted by the Client.
            """
            raise IssuerDoesNotMatch("Issuer does not match")

        if decoded_token["aud"] != self.config.client_id:
            raise InvalidClientID("Audience does not match client_id")
        """ Step 6 : TLS server validation not implemented by Okta
            If ID Token is received via direct communication between Client and
            Token Endpoint, TLS server validation may be used to validate the
            issuer in place of checking token
            signature. MUST validate according to JWS algorithm specialized in JWT
            alg Header. MUST use keys provided.
        """
        """ Step 7
            The alg value SHOULD default to RS256 or sent in
            id_token_signed_response_alg param during Registration

            We don't need to test this. Okta always signs in RS256
        """
        """ Step 8 : Not implemented due to Okta configuration

            If JWT alg Header uses MAC based algorithm (HS256, HS384, etc) the
            octets of UTF-8 of the client_secret corresponding to the client_id
            are contained in the aud (audience) are used to validate the signature.
            For MAC based, if aud is multi-valued or if azp value is different
            than aud value - behavior is unspecified.
        """

        if decoded_token["exp"] < int(time.time()):
            """Step 9
            The current time MUST be before the time represented by exp
            """
            raise TokenExpired

        if decoded_token["iat"] < (int(time.time()) - 100000):
            """Step 10 - Defined 'too far away time' : approx 24hrs
            The iat can be used to reject tokens that were issued too far away
            from current time, limiting the time that nonces need to be stored
            to prevent attacks.
            """
            raise TokenTooFarAway("iat too far in the past ( > 1 day)")

        if self.nonce is not None and "nonce" in decoded_token:
            """Step 11
            If a nonce value is sent in the Authentication Request,
            a nonce MUST be present and be the same value as the one
            sent in the Authentication Request. Client SHOULD check for
            nonce value to prevent replay attacks.
            """
            if self.nonce != decoded_token["nonce"]:
                raise NonceDoesNotMatch(
                    "nonce value does not match Authentication Request nonce")
        """ Step 12:  Not implemented by Okta
            If acr was requested, check that the asserted Claim Value is appropriate
        """
        """ Step 13
            If auth_time was requested, check claim value and request
            re-authentication if too much time elapsed

            We relax this requirement during jwt validation. The Okta Session
            should be handled inside Okta

            See https://developer.okta.com/docs/api/resources/sessions
        """

        return decoded_token
Esempio n. 13
0
def verify_decode_jwt(token):
    #jsonurl = urlopen(f'https://{AUTH0_DOMAIN}/.well-known/jwks.json')
    jsonurl = urlopen(f"https://" + AUTH0_DOMAIN + "/.well-known/jwks.json")
    jwks = json.loads(jsonurl.read())

    unverified_header = jwt.get_unverified_header(token)
    print("unver_header", unverified_header)
    rsa_key = {}

    if 'kid' not in unverified_header:
        print('FAIl')
        raise AuthError(
            {
                'code': 'invalid_header',
                'description': 'Authorization malformed'
            }, 401)

    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,
                                 rsa_key,
                                 algorithms=ALGORITHMS,
                                 audience=API_AUDIENCE,
                                 issuer='https://' + AUTH0_DOMAIN + '/')
            print("payload", payload)
            return payload

        except jwt.ExpiredSignatureError:
            raise AuthError(
                {
                    'code': 'token_expired',
                    'description': 'Token expired'
                }, 401)
        except jwt.JWTClaimsError:
            raise AuthError(
                {
                    'code': 'invalid_claims',
                    'description':
                    'Incorrect claims. Check audience and issuer'
                }, 401)
        except Exception:
            raise AuthError(
                {
                    'code': 'invalid_header',
                    'description': 'Unable to parse authentication token.'
                }, 401)

    print("rsa_key", rsa_key)
    raise AuthError(
        {
            'code': 'invalid_header',
            'description': 'Unable to locate the appropriate key'
        }, 401)
Esempio n. 14
0
async def get_current_token(
    security_scopes: SecurityScopes,
    token: str = Depends(hydra_scheme)) -> dict:
    async with AsyncClient() as session:
        resp = await session.get(settings.hydra_url + "/.well-known/jwks.json")
        jwks = resp.json()
        unverified_header = jwt.get_unverified_header(token)

        rsa_key = dict()
        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,
                                     rsa_key,
                                     audience="",
                                     algorithms=settings.hydra_algorithms,
                                     issuer=settings.hydra_issuer_url + "/",
                                     options={'verify_aud': False})
            except jwt.ExpiredSignatureError as e:
                raise AuthError(
                    {
                        "code": "token_expired",
                        "description": "Token is expired",
                        "error": str(e)
                    }, 401)
            except jwt.JWTClaimsError as e:
                raise AuthError(
                    {
                        "code": "invalid_claims",
                        "description":
                        "Incorrect claims, please check the audience and issuer",
                        "error": str(e)
                    },
                    401,
                )
            except Exception as e:
                raise AuthError(
                    {
                        "code": "invalid_header",
                        "description": "Unable to parse authentication token.",
                        "error": str(e)
                    },
                    401,
                )

            token_scopes = payload.get("scp", "")
            for scope in security_scopes.scopes:
                if scope not in token_scopes:
                    raise AuthError(
                        {
                            "code":
                            "Unauthorized",
                            "description":
                            "You don't have access to this resource. {} scopes required"
                            .format(" ".join(security_scopes.scopes)),
                        }, 403)

            return payload
Esempio n. 15
0
def verify_decode_jwt(token):
    try:
        jwt_unverified_headers = jwt.get_unverified_header(token)
    except jwt.JWTError:
        raise AuthError({
            'status': 401,
            'message': 'invalid jwt token'
        },
                        status_code=401)
    public_keys_url = f' https://{AUTH0_DOMAIN}/.well-known/jwks.json'
    response = requests.get(public_keys_url)
    jwks = response.json() if response.status_code == 200 else None
    if 'kid' not in jwt_unverified_headers:
        raise AuthError({
            'status': 401,
            'message': 'invalid jwt token'
        },
                        status_code=401)
    if jwks:
        matched_key = {}
        if 'keys' in jwks:
            for key in jwks['keys']:
                if key['kid'] == jwt_unverified_headers['kid']:
                    matched_key = key
        if matched_key:
            try:
                issuer = f'https://{AUTH0_DOMAIN}/'
                decoded_jwt = jwt.decode(
                    token,
                    matched_key,
                    algorithms=JWT_TOKEN_ENCRYPTION_ALGORITHMS,
                    audience=AUTH0_JWT_API_AUDIENCE,
                    issuer=issuer)
                return decoded_jwt
            except jwt.ExpiredSignatureError:
                raise AuthError({
                    'status': 401,
                    'message': 'token has expired'
                },
                                status_code=401)
            except jwt.JWTClaimsError:
                raise AuthError(
                    {
                        'status': 401,
                        'message': 'invalid claim in jwt token'
                    },
                    status_code=401)
            except jwt.JWTError:
                raise AuthError({
                    'status': 401,
                    'message': 'invalid signature'
                },
                                status_code=401)
            except Exception:
                print(sys.exc_info())
                raise AuthError(
                    {
                        'status': 401,
                        'message': 'invalid auth token'
                    },
                    status_code=401)
            except Exception:
                print(sys.exc_info())
                raise AuthError({
                    'status': 500,
                    'message': 'token has expired'
                },
                                status_code=500)
        raise AuthError(
            {
                'code': 'invalid token',
                'description': 'please provide a valid token.'
            }, 401)
    raise AuthError(
        {
            'code': 'invalid token',
            'description': 'please provide a valid token.'
        }, 401)
Esempio n. 16
0
    def decorated(*args, **kwargs):
        token = get_token_auth_header()

        # Commented the next two lines because they are causing data type related errors
        # jsonurl = urlopen("https://souhail.auth0.com/.well-known/jwks.json")
        # jwks = json.loads(jsonurl.read())

        # The previous two lines were replace by the next two one, in order to load the json file as usual
        jsonurl_requests = requests.get(
            "https://"+AUTH0_DOMAIN+"/.well-known/jwks.json")
        jwks = jsonurl_requests.json()
        try:
            unverified_header = jwt.get_unverified_header(token)
        except jwt.JWTError:
            raise AuthError({"code": "invalid_header",
                             "description":
                             "Invalid header. "
                             "Use an RS256 signed JWT Access Token"}, 401)
        if unverified_header["alg"] == "HS256":
            raise AuthError({"code": "invalid_header",
                             "description":
                             "Invalid header. "
                             "Use an RS256 signed JWT Access Token"}, 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,
                    rsa_key,
                    algorithms=ALGORITHMS,
                    audience=AUTH0_AUDIENCE,
                    issuer="https://"+AUTH0_DOMAIN+"/"
                )
                # The next lines commented out as they are causing the mis-interpretation of the payload
                #,
                #    issuer=AUTH0_DOMAIN
            except jwt.ExpiredSignatureError:
                raise AuthError({"code": "token_expired",
                                 "description": "token is expired"}, 401)
            except jwt.JWTClaimsError:
                raise AuthError({"code": "invalid_claims",
                                 "description":
                                 "incorrect claims,"
                                 " please check the audience and issuer"}, 401)
            except Exception:
                raise AuthError({"code": "invalid_header",
                                 "description":
                                 "Unable to parse authentication"
                                 " token."}, 400)

            _request_ctx_stack.top.current_user = payload
            return f(*args, **kwargs)
        raise AuthError({"code": "invalid_header",
                         "description": "Unable to find appropriate key"}, 400)
Esempio n. 17
0
def verify_decode_jwt(token):
    """ Decodes JWT Token or raises appropiate Error Messages
    """
    # Verify token
    jsonurl = urlopen(f"https://{AUTH0_DOMAIN}/.well-known/jwks.json")
    jwks = json.loads(jsonurl.read())
    unverified_header = jwt.get_unverified_header(token)

    # Check if Key id is in unverified header
    if "kid" not in unverified_header:
        raise AuthError(
            {
                "code": "invalid_header",
                "description": "Authorization malformed."
            }, 401)

    rsa_key = {}  # initialize empty private rsa key as dict
    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,
                rsa_key,
                algorithms=ALGORITHMS,
                audience=API_AUDIENCE,
                issuer="https://" + AUTH0_DOMAIN + "/",
            )
            return payload

        # Raise Error if token is not valide anymore.
        except jwt.ExpiredSignatureError:
            raise AuthError(
                {
                    "code": "token_expired",
                    "description": "Token expired."
                }, 401)

        except jwt.JWTClaimsError:
            raise AuthError(
                {
                    "code":
                    "invalid_claims",
                    "description":
                    "Incorrect claims.\
                    Please, check the audience and issuer.",
                },
                401,
            )

        except Exception:
            raise AuthError(
                {
                    "code": "invalid_header",
                    "description": "Unable to parse authentication token.",
                },
                400,
            )

    # If no payload has been returned yet, raise error.
    raise AuthError(
        {
            "code": "invalid_header",
            "description": "Unable to find the appropriate key.",
        },
        400,
    )
Esempio n. 18
0
def verify_decode_jwt(token):
    """
    Used to verify and decode the token
    NOTES: https://stackoverflow.com/questions/50236117/scraping-ssl-certificate-verify-failed-error-for-http-en-wikipedia-org
    :param token:
    :return: payload
    """
    # GET THE PUBLIC KEY FROM AUTH0
    jsonurl = urlopen(f'https://{AUTH0_DOMAIN}/.well-known/jwks.json')
    jwks = json.loads(jsonurl.read())

    # GET THE DATA IN THE HEADER
    unverified_header = jwt.get_unverified_header(token)

    # CHOOSE OUR KEY
    rsa_key = {}
    if 'kid' not in unverified_header:
        raise AuthError(
            {
                'code': 'invalid_header',
                'description': 'Authorization malformed.'
            }, 401)

    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']
            }

    # Verify key
    if rsa_key:
        try:
            # USE THE KEY TO VALIDATE THE JWT
            payload = jwt.decode(token,
                                 rsa_key,
                                 algorithms=ALGORITHMS,
                                 audience=API_AUDIENCE,
                                 issuer='https://' + AUTH0_DOMAIN + '/')

            return payload

        except jwt.ExpiredSignatureError:
            raise AuthError(
                {
                    'code': 'token_expired',
                    'description': 'Token expired.'
                }, 401)

        except jwt.JWTClaimsError:
            raise AuthError(
                {
                    'code':
                    'invalid_claims',
                    'description':
                    'Incorrect claims. Please, check the audience and issuer.'
                }, 401)
        except Exception:
            raise AuthError(
                {
                    'code': 'invalid_header',
                    'description': 'Unable to parse authentication token.'
                }, 400)
    raise AuthError(
        {
            'code': 'invalid_header',
            'description': 'Unable to find the appropriate key.'
        }, 400)
Esempio n. 19
0
def check_auth():
    """Determines if the Access Token is valid
    """
    domain_base = "https://" + AUTH0_DOMAIN + "/"
    token = get_token_auth_header()

    if token in auth0_cache:
        return auth0_cache[token]

    # check token validity
    jsonurl = urlopen(domain_base + ".well-known/jwks.json")
    jwks = json.loads(jsonurl.read())

    try:
        unverified_header = jwt.get_unverified_header(token)
    except JWTError:
        raise AuthError({"code": "improper_token",
                        "description": "Token cannot be validated"}, 403)

    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"]
            }
            break
    else:
        raise AuthError({"code": "invalid_header",
                         "description": "Unable to find appropriate key"}, 403)

    try:
        payload = jwt.decode(
            token,
            rsa_key,
            algorithms=AUTH0_ALGORITHMS,
            audience=AUTH0_API_AUDIENCE,
            issuer=domain_base
        )
    except jwt.ExpiredSignatureError:
        raise AuthError({"code": "token_expired",
                        "description": "Token is expired"}, 403)
    except jwt.JWTClaimsError:
        raise AuthError({"code": "invalid_claims",
                        "description":
                            "Incorrect claims,"
                            "please check the audience and issuer"}, 403)
    except Exception:
        raise AuthError({"code": "invalid_header",
                        "description":
                            "Unable to parse authentication"
                            " token."}, 403)

    # check scope
    unverified_claims = jwt.get_unverified_claims(token)
    if unverified_claims.get("scope"):
        token_scopes = unverified_claims["scope"].split()
        for token_scope in token_scopes:
            if token_scope == AUTH0_REQUIRED_SCOPE:
                _request_ctx_stack.top.current_user = payload
                auth0_cache[token] = True
                return True

    raise AuthError({"code": "access_denied",
                     "description": "Access not allowed"}, 403)
Esempio n. 20
0
def verify_decode_jwt(token):
    url_string = "https://{}/.well-known/jwks.json".format(AUTH0_DOMAIN)
    json_url = urlopen(url_string)
    jwks = json.loads(json_url.read())
    unverified_header = jwt.get_unverified_header(token)
    rsa_key = {}

    if 'kid' not in unverified_header:
        raise AuthError(
            {
                'code': 'invalid_authorization_header',
                'description': 'Authorization Header is malformed.'
            }, 401)

    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,
                                 rsa_key,
                                 algorithms=ALGORITHMS,
                                 audience=API_AUDIENCE,
                                 issuer='https://{}/'.format(AUTH0_DOMAIN))

            return payload

        except jwt.ExpiredSignatureError:
            raise AuthError(
                {
                    'code': 'token_expired',
                    'description': 'Token expired.'
                }, 401)

        except jwt.JWTClaimsError:
            raise AuthError(
                {
                    'code':
                    'invalid_claims',
                    'description':
                    'Incorrect claims. Please check the audience and issuer.'
                }, 401)

        except Exception:
            raise AuthError(
                {
                    'code': 'invalid_authorization_header',
                    'description': 'Unable to parse authentication token.'
                }, 401)

    raise AuthError(
        {
            'code': 'invalid_authorization_header',
            'description': 'Unable to find the appropriate key.'
        }, 401)
Esempio n. 21
0
def get_id_token_payload(token):
    """Determines if the access token is valid
    """

    print("Enter get_id_token_payload")

    print("requires_auth token = " + token)
    jsonurl = urlopen("https://" + AUTH0_DOMAIN + "/.well-known/jwks.json")
    jwks = json.loads(jsonurl.read().decode("utf8"))
    print("jwks" + jsonurl.read().decode("utf8"))

    try:
        unverified_header = jwt.get_unverified_header(token)
    except jwt.JWTError:
        raise AuthError(
            {
                "code":
                "invalid_header",
                "description":
                "Invalid header. "
                "Use an RS256 signed JWT Access Token"
            }, 401)
    if unverified_header["alg"] == "HS256":
        raise AuthError(
            {
                "code":
                "invalid_header HS",
                "description":
                "Invalid header. "
                "Use an HS S256 signed JWT Access Token"
            }, 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"]
            }
    print("rsa_key =", rsa_key)
    if rsa_key:
        try:
            payload = jwt.decode(token,
                                 rsa_key,
                                 algorithms=ALGORITHMS,
                                 audience="QN3TAKTeDu4U4i6tfVI2JCs7hXSxdePG",
                                 issuer="https://" + AUTH0_DOMAIN + "/")

            print("payload :", json.dumps(payload, indent=2))
            #return json.dumps(payload, indent=2)
            return payload
        except jwt.ExpiredSignatureError:
            raise AuthError(
                {
                    "code": "token_expired",
                    "description": "token is expired"
                }, 401)
        except jwt.JWTClaimsError as e:
            print(e)
            #print(API_IDENTIFIER)
            raise AuthError(
                {
                    "code":
                    "invalid_claims",
                    "description":
                    "incorrect claims,"
                    " please check the audience and issuer"
                }, 401)
        except Exception:
            raise AuthError(
                {
                    "code": "invalid_header",
                    "description": "Unable to parse authentication"
                    " token."
                }, 401)
Esempio n. 22
0
def verify_decode_jwt(token):
    """
    Reference:
    - Identity and Access Management course's videos
    - https://github.com/udacity/FSND/tree/master/BasicFlaskAuth
    """
    jsonurl = urlopen(f'https://{AUTH0_DOMAIN}/.well-known/jwks.json')
    jwks = json.loads(jsonurl.read())
    unverified_header = jwt.get_unverified_header(token)
    rsa_key = {}
    if 'kid' not in unverified_header:
        raise AuthError(
            {
                'code': 'invalid_header',
                'description': 'Authorization malformed.'
            }, 401)

    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,
                                 rsa_key,
                                 algorithms=ALGORITHMS,
                                 audience=API_AUDIENCE,
                                 issuer='https://' + AUTH0_DOMAIN + '/')

            return payload

        except jwt.ExpiredSignatureError:
            raise AuthError(
                {
                    'code': 'token_expired',
                    'description': 'Token expired.'
                }, 401)

        except jwt.JWTClaimsError:
            raise AuthError(
                {
                    'code':
                    'invalid_claims',
                    'description':
                    'Incorrect claims. Please, check the audience and issuer.'
                }, 401)
        except Exception:
            raise AuthError(
                {
                    'code': 'invalid_header',
                    'description': 'Unable to parse authentication token.'
                }, 400)
    raise AuthError(
        {
            'code': 'invalid_header',
            'description': 'Unable to find the appropriate key.'
        }, 400)
Esempio n. 23
0
def verify_decode_jwt(token):
    # Retrieve the JSON Web Key Set (JWKS) that is used to verify JWT issued by Auth0
    jsonurl = urlopen(f'https://{AUTH0_DOMAIN}/.well-known/jwks.json')
    jwks = json.loads(jsonurl.read())
    unverified_header = jwt.get_unverified_header(token)
    rsa_key = {}

    # Filter out any key missing a public key and a kid property.
    if 'kid' not in unverified_header:
        raise AuthError(
            {
                'code': 'invalid_header',
                'description': 'Authorization malformed.'
            }, 401)

    # Find the signing key using the value of the kid property.
    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']
            }

    # Decode jwt token
    if rsa_key:
        try:
            payload = jwt.decode(token,
                                 rsa_key,
                                 algorithms=ALGORITHMS,
                                 audience=API_AUDIENCE,
                                 issuer='https://' + AUTH0_DOMAIN + '/')
            return payload

        except jwt.ExpiredSignatureError:
            raise AuthError(
                {
                    'code': 'token_expired',
                    'description': 'Token expired.'
                }, 401)

        except jwt.JWTClaimsError:
            raise AuthError(
                {
                    'code':
                    'invalid_claims',
                    'description':
                    'Incorrect claims. Please, check the audience and issuer.'
                }, 401)
        except Exception:
            raise AuthError(
                {
                    'code': 'invalid_header',
                    'description': 'Unable to parse authentication token.'
                }, 400)
    raise AuthError(
        {
            'code': 'invalid_header',
            'description': 'Unable to find the appropriate key.'
        }, 400)
Esempio n. 24
0
def verify_decode_jwt(token):
    """Verify a json web token and decode the payload from it

    Args:
        string: a json web token

    Returns:
        the decoded payload
    """
    jsonurl = urlopen(f'https://{AUTH0_DOMAIN}/.well-known/jwks.json')
    jwks = json.loads(jsonurl.read())

    unverified_header = jwt.get_unverified_header(token)
    if 'kid' not in unverified_header:
        raise AuthError(
            {
                'status': 'invalid_header',
                'message': 'Authorization malformed.'
            }, 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 not rsa_key:
        raise AuthError(
            {
                'status': 'invalid_header',
                'message': 'Unabble to find the appropriate key.'
            }, 401)

    try:
        payload = jwt.decode(token,
                             rsa_key,
                             algorithms=ALGORITHMS,
                             audience=API_AUDIENCE,
                             issuer=f'https://{AUTH0_DOMAIN}/')
        return payload

    except jwt.ExpiredSignatureError:
        raise AuthError(
            {
                'status': 'token_expired',
                'message': 'Token expired.'
            }, 401)

    except jwt.JWTClaimsError:
        raise AuthError(
            {
                'status':
                'invalid_claims',
                'message':
                'Incorrect claims. Please, check the audience and issuer.'
            }, 401)

    except Exception:
        raise AuthError(
            {
                'status': 'invalid_header',
                'message': 'Unable to parse authentication token.'
            }, 401)
Esempio n. 25
0
def verify_decode_jwt(token):
    # get the public key of the auth server
    jsonurl = urlopen(f'https://{AUTH0_DOMAIN}/.well-known/jwks.json')
    jwks = json.loads(jsonurl.read())
    # decode the payload from the token
    unverified_header = jwt.get_unverified_header(token)

    rsa_key = {}
    if 'kid' not in unverified_header:
        raise AuthError(
            {
                'code': 'invalid_header',
                'description': 'Authorization malformed.'
            }, 401)

    # if key id match, then build the 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,
                                 rsa_key,
                                 algorithms=ALGORITHMS,
                                 audience=API_AUDIENCE,
                                 issuer='https://' + AUTH0_DOMAIN + '/')

            return payload

        except jwt.ExpiredSignatureError as ex:
            print(ex)
            raise AuthError(
                {
                    'code': 'token_expired',
                    'description': 'Token expired.'
                }, 401)

        except jwt.JWTClaimsError as ex:
            print(ex)
            raise AuthError(
                {
                    'code':
                    'invalid_claims',
                    'description':
                    'Incorrect claims. Please, check the audience and issuer.'
                }, 401)

        except Exception as ex:
            print(ex)
            raise AuthError(
                {
                    'code': 'invalid_header',
                    'description': 'Unable to parse authentication token.'
                }, 400)

    raise AuthError(
        {
            'code': 'invalid_header',
            'description': 'Unable to find the appropriate key.'
        }, 401)
Esempio n. 26
0
    def verify_decode_jwt(self, token):
        json_url = urlopen(self.JSON_URL)
        jwks = json.loads(json_url.read())

        try:
            unverified_header = jwt.get_unverified_header(token)
        except jwt.JWTError:
            raise AuthError(
                {
                    'code': 401,
                    'message': 'Error decoding token headers.'
                }, 401)
        rsa_key = {}

        if 'kid' not in unverified_header:
            raise AuthError(
                {
                    'code': 401,
                    'message': 'Authorization malformed.'
                }, 401)

        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,
                                     rsa_key,
                                     algorithms=self.ALGORITHMS,
                                     audience=self.API_AUDIENCE,
                                     issuer='https://' + self.AUTH0_DOMAIN +
                                     '/')

                return payload
            except jwt.ExpiredSignatureError:
                raise AuthError({
                    'code': 401,
                    'message': 'Token expired.'
                }, 401)
            except jwt.JWTClaimsError:
                raise AuthError(
                    {
                        'code':
                        401,
                        'message':
                        'Incorrect claims. Please, check the audience and issuer.'
                    }, 401)
            except Exception:
                raise AuthError(
                    {
                        'code': 401,
                        'message': 'Unable to parse authentication token.'
                    }, 401)

        raise AuthError(
            {
                'code': 401,
                'message': 'Unable to find the appropriate key.'
            }, 401)
Esempio n. 27
0
def verify_decode_jwt(token):
    jsonurl = urlopen(
        f'https://{os.environ["AUTH0_DOMAIN"]}/.well-known/jwks.json')
    jwks = json.loads(jsonurl.read())
    unverified_header = jwt.get_unverified_header(token)
    rsa_key = {}
    if 'kid' not in unverified_header:
        raise AuthError(
            {
                'code': 'invalid_header',
                'description': 'Authorization malformed'
            }, 401)

    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,
                rsa_key,
                algorithms=os.environ['ALGORITHMS'],
                audience=os.environ['API_AUDIENCE'],
                issuer=f'https://{os.environ["AUTH0_DOMAIN"]}/')
            return payload

        except jwt.ExpiredSignatureError:
            raise AuthError(
                {
                    'code': 'token_expired',
                    'description': 'Token expired'
                }, 401)

        except jwt.JWTClaimsError:
            raise AuthError(
                {
                    'code':
                    'invalid_claims',
                    'description':
                    'Incorrect claims, please, check the audience and issuer'
                }, 401)

        except Exception:
            raise AuthError(
                {
                    'code': 'invalid_header',
                    'description': 'Unable to parse authentication token'
                }, 400)

    raise AuthError(
        {
            'code': 'invalid_header',
            'description': 'Unable to find the appropriate key'
        }, 401)
Esempio n. 28
0
def verify_decode_jwt(token):
    #GET THE PUBLI KEY FROM AUTH0
    jsonurl = urlopen(f'https://{AUTH0_DOMAIN}/.well-known/jwks.json')
    jwks = json.loads(jsonurl.read())

    #GET THE DATA IN THE HEADER
    unverified_header = jwt.get_unverified_header(token)
    print("check kid")
    print('kid' not in unverified_header)
    #CHOOSE OUR KEY
    rsa_key = {}
    if 'kid' not in unverified_header:
        #raise AuthError({
        #    'code': 'invalid_header',
        #    'description': 'Authorization malformed'
        #}, 401)
        abort(401)

    print("kid present")
    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']
            }

    print("rsa key created")
    #Finally verify
    if rsa_key:
        try:
            #use the key to validate the jwt
            payload = jwt.decode(token,
                                 rsa_key,
                                 algorithms=ALGORITHMS,
                                 audience=API_AUDIENCE,
                                 issuer='https://' + AUTH0_DOMAIN + '/')
            print('token verified')
            return payload

        except jwt.ExpiredSignatureError:
            raise AuthError(
                {
                    'code': 'token_expired',
                    'description': 'Token expired'
                }, 401)
            #abort(401)

        except jwt.JWTClaimsError:
            raise AuthError(
                {
                    'code': 'invalid_claims',
                    'description': 'Incorrect claims'
                }, 401)
            #abort(401)

        except Exception:
            raise AuthError(
                {
                    'code': 'invalid_header',
                    'description': 'Unable to pass token'
                }, 400)
Esempio n. 29
0
def verify_decode_jwt(token):
    jsonurl = urlopen(f'https://{AUTH0_DOMAIN}/.well-known/jwks.json')
    jwks = json.loads(jsonurl.read())
    unverified_header = jwt.get_unverified_header(token)
    rsa_key = {}
    if 'kid' not in unverified_header:
        raise AuthError(
            {
                'code': 'invalid_header',
                'description': 'Authorization malformed.'
            }, 401)

    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 not rsa_key:
        raise AuthError(
            {
                'code': 'invalid_header',
                'description': 'Unable to find the appropriate key.'
            }, 400)
    else:
        try:
            payload = jwt.decode(token,
                                 rsa_key,
                                 algorithms=ALGORITHMS,
                                 options=JWT_VALIDATION_CONFIG,
                                 audience=API_AUDIENCE,
                                 issuer='https://' + AUTH0_DOMAIN + '/')

        except jwt.ExpiredSignatureError:
            raise AuthError(
                {
                    'code': 'token_expired',
                    'description': 'Token expired.'
                }, 401)

        except jwt.JWTClaimsError:
            raise AuthError(
                {
                    'code':
                    'invalid_claims',
                    'description':
                    'Incorrect claims. Please, check the audience and issuer.'
                }, 401)

        # catch the rest of exceptions
        except Exception:
            raise AuthError(
                {
                    'code': 'invalid_header',
                    'description': 'Unable to parse authentication token.'
                }, 400)

        return payload
Esempio n. 30
0
def verify_decode_jwt(token):
    """ Checks that jwt is valid and return decoded token in a dict
        Params:
            - token [type: str]: JWT passed from authentication

        - Raises [code#, code]:
            - [401, 'token_expired]: Token is expired
            - [401, 'invalid_claims]: Incorrect claims
            - [400, 'invalid_header]: unable to parse authentication token
            - [400, 'invalid_header]: Unable to find appropriate key

    """
    # get the public key from auth0
    jsonurl = urlopen(f'https://{AUTH0_DOMAIN}/.well-known/jwks.json')
    jwks = json.loads(jsonurl.read())

    # get the data in header
    unverified_header = jwt.get_unverified_header(token)

    # get key
    rsa_key = {}
    if 'kid' not in unverified_header:
        raise AuthError({
            'code': 'invalid_header',
            'description': 'Authorization malformed.'
        }, 401)

    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:
            # use the key to validate the JWT
            payload = jwt.decode(
                token,
                rsa_key,
                algorithms=ALGORITHMS,
                audience=API_AUDIENCE,
                issuer='https://' + AUTH0_DOMAIN + '/'
            )
            return payload
        # token is experpied
        except jwt.ExpiredSignatureError:
            raise AuthError({
                'code': 'token_expired',
                'description': 'Token expired.'
            }, 401)
        # user does not have valid claim
        except jwt.JWTClaimsError:
            raise AuthError({
                'code': 'invalid_claims',
                'description': """Incorrect claims.
                Please check the audience and issuer."""
            }, 401)
        # token has error
        except Exception:
            raise AuthError({
                'code': 'invalid_header',
                'description': 'Unable to parse authentication token.'
            }, 400)

    raise AuthError({
        'code': 'invalid_header',
        'description': 'Unable to find the appropriate key.'
    }, 400)
Esempio n. 31
0
def verify_decode_jwt(token):
    # Get public key from Auth0
    jsonurl = urlopen(f"https://{AUTH0_DOMAIN}/.well-known/jwks.json")
    jwks = json.loads(jsonurl.read())
    # Extract header data from the token
    unverified_header = jwt.get_unverified_header(token)
    # Initialize RSA Key
    rsa_key = dict()
    # Raize 401 error if token header doesn't contain: kid
    if "kid" not in unverified_header:
        raise AuthError(
            {"code": "invalid_header", "description": "Authorization malformed."}, 401,
        )

    for key in jwks["keys"]:
        # Create the RSA Key of a match exists
        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:
            # Validate the token
            payload = jwt.decode(
                token,
                rsa_key,
                algorithms=ALGORITHMS,
                audience=API_AUDIENCE,
                issuer="https://" + AUTH0_DOMAIN + "/",
            )
            return payload
        # Check for JWT errors
        except jwt.ExpiredSignatureError:
            raise AuthError(
                {"code": "token_expired", "description": "Token expired."}, 401
            )
        except jwt.JWTClaimsError:
            raise AuthError(
                {
                    "code": "invalid_claims",
                    "description": "Incorrect claims. Please, check the audience and issuer.",
                },
                401,
            )
        except Exception:
            raise AuthError(
                {
                    "code": "invalid_header",
                    "description": "Unable to parse authentication token.",
                },
                400,
            )
    # Raise 400 error if Key not found
    raise AuthError(
        {
            "code": "invalid_header",
            "description": "Unable to find the appropriate key.",
        },
        400,
    )
Esempio n. 32
0
def verify_decode_jwt(token):

    # Verify token
    jsonurl = urlopen(f'https://{AUTH0_DOMAIN}/.well-known/jwks.json')
    jwks = json.loads(jsonurl.read())
    unverified_header = jwt.get_unverified_header(token)

    # Check if Key id is in unverified header
    if 'kid' not in unverified_header:
        raise AuthError(
            {
                'code': 'invalid_header',
                'description': 'Authorization malformed.'
            }, 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:
            # Use Auth Config to decode JWT
            payload = jwt.decode(token,
                                 rsa_key,
                                 algorithms=ALGORITHMS,
                                 audience=API_AUDIENCE,
                                 issuer='https://' + AUTH0_DOMAIN + '/')
            return payload

        # Raise if token is not valid
        except jwt.ExpiredSignatureError:
            raise AuthError(
                {
                    'code': 'token_expired',
                    'description': 'Token expired.'
                }, 401)

        # Error if wrong audience
        except jwt.JWTClaimsError:
            raise AuthError(
                {
                    'code':
                    'invalid_claims',
                    'description':
                    'Incorrect claims. Please, check the audience and issuer.'
                }, 401)

        # In all other Error cases
        except Exception:
            raise AuthError(
                {
                    'code': 'invalid_header',
                    'description': 'Unable to parse authentication token.'
                }, 400)

    # raise error if no payload.
    raise AuthError(
        {
            'code': 'invalid_header',
            'description': 'Unable to find the appropriate key.'
        }, 400)
Esempio n. 33
0
def verify_decode_jwt(token):
    # GET THE PUBLIC KEY FROM AUTH0
    jsonurl = urlopen(f'https://{AUTH0_DOMAIN}/.well-known/jwks.json')
    jwks = json.loads(jsonurl.read())

    # GET THE DATA IN THE HEADER
    unverified_header = jwt.get_unverified_header(token)

    # CHOOSE OUR KEY
    rsa_key = {}
    if 'kid' not in unverified_header:
        raise AuthError(
            {
                'code': 'invalid_header',
                'description': 'Authorization malformed.'
            }, 401)

    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']
            }

    # Finally, verify!!!
    if rsa_key:
        try:
            # USE THE KEY TO VALIDATE THE JWT
            payload = jwt.decode(token,
                                 rsa_key,
                                 algorithms=ALGORITHMS,
                                 audience=API_AUDIENCE,
                                 issuer='https://' + AUTH0_DOMAIN + '/')

            return payload

        except jwt.ExpiredSignatureError:
            raise AuthError(
                {
                    'code': 'token_expired',
                    'description': 'Token expired.'
                }, 401)

        except jwt.JWTClaimsError:
            raise AuthError(
                {
                    'code':
                    'invalid_claims',
                    'description':
                    'Incorrect claims. Please, check the audience and issuer.'
                }, 401)
        except Exception:
            raise AuthError(
                {
                    'code': 'invalid_header',
                    'description': 'Unable to parse authentication token.'
                }, 400)
    raise AuthError(
        {
            'code': 'invalid_header',
            'description': 'Unable to find the appropriate key.'
        }, 400)
Esempio n. 34
0
def verify_jwt(request):
    if 'Authorization' not in request.headers:
        raise AuthError(
            {
                "code": "invalid_header",
                "description": "Invalid header. "
                "No authorization provided"
            }, 401)

    auth_header = request.headers['Authorization'].split()
    token = auth_header[1]

    jsonurl = urlopen("https://" + DOMAIN + "/.well-known/jwks.json")
    jwks = json.loads(jsonurl.read())
    try:
        unverified_header = jwt.get_unverified_header(token)
    except jwt.JWTError:
        raise AuthError(
            {
                "code":
                "invalid_header",
                "description":
                "Invalid header. "
                "Use an RS256 signed JWT Access Token"
            }, 401)
    if unverified_header["alg"] == "HS256":
        raise AuthError(
            {
                "code":
                "invalid_header",
                "description":
                "Invalid header. "
                "Use an RS256 signed JWT Access Token"
            }, 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,
                                 rsa_key,
                                 algorithms=ALGORITHMS,
                                 audience=CLIENT_ID,
                                 issuer="https://" + DOMAIN + "/")
        except jwt.ExpiredSignatureError:
            raise AuthError(
                {
                    "code": "token_expired",
                    "description": "token is expired"
                }, 401)
        except jwt.JWTClaimsError:
            raise AuthError(
                {
                    "code":
                    "invalid_claims",
                    "description":
                    "incorrect claims,"
                    " please check the audience and issuer"
                }, 401)
        except Exception:
            raise AuthError(
                {
                    "code": "invalid_header",
                    "description": "Unable to parse authentication"
                    " token."
                }, 401)

        return payload
    else:
        raise AuthError(
            {
                "code": "no_rsa_key",
                "description": "No RSA key in JWKS"
            }, 401)
Esempio n. 35
0
    def decorated(*args, **kwargs):
        auth = request.headers.get('Authorization', None)
        if not auth:
            return handle_error(
                {
                    'code': 'authorization_header_missing',
                    'description': 'Authorization header is expected'
                }, 401)

        parts = auth.split()

        if parts[0].lower() != 'bearer':
            return handle_error(
                {
                    'code': 'invalid_header',
                    'description': 'Authorization header must start with'
                    'Bearer'
                }, 401)
        elif len(parts) == 1:
            return handle_error(
                {
                    'code': 'invalid_header',
                    'description': 'Token not found'
                }, 401)
        elif len(parts) > 2:
            return handle_error(
                {
                    'code':
                    'invalid_header',
                    'description':
                    'Authorization header must be'
                    'Bearer + \s + token'
                }, 401)

        token = parts[1]
        jsonurl = urllib.urlopen('https://' + auth0_domain +
                                 '/.well-known/jwks.json')
        jwks = json.loads(jsonurl.read())
        unverified_header = jwt.get_unverified_header(token)
        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,
                                     rsa_key,
                                     algorithms=unverified_header['alg'],
                                     audience=api_audience,
                                     issuer='https://' + auth0_domain + '/')
            except jwt.ExpiredSignatureError:
                return handle_error(
                    {
                        'code': 'token_expired',
                        'description': 'token is expired'
                    }, 401)
            except jwt.JWTClaimsError:
                return handle_error(
                    {
                        'code':
                        'invalid_claims',
                        'description':
                        'incorrect claims, please check the audience and issuer'
                    }, 401)
            except Exception:
                return handle_error(
                    {
                        'code': 'invalid_header',
                        'description': 'Unable to parse authentication'
                        ' token.'
                    }, 400)

            _app_ctx_stack.top.current_user = payload
            return f(*args, **kwargs)
        return handle_error(
            {
                'code': 'invalid_header',
                'description': 'Unable to find appropriate key'
            }, 400)
Esempio n. 36
0
def verify_decode_jwt(token):
    # print('token passed to function',token)
    try:
        # GET THE PUBLIC KEY FROM AUTH0
        jsonurl = urlopen(f'https://{AUTH0_DOMAIN}/.well-known/jwks.json',
                          context=ssl_context)
        # print('verify 2')
        jwks = json.loads(jsonurl.read())
        # print('verify 3')

        # GET THE DATA IN THE HEADER
        unverified_header = jwt.get_unverified_header(token)
        # print('verify 4', unverified_header)

        # CHOOSE OUR KEY
        rsa_key = {}
        if 'kid' not in unverified_header:
            raise AuthError(
                {
                    'code': 'invalid_header',
                    'description': 'Authorization malformed.'
                }, 401)

        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']
                }

        # Finally, verify!!!
        if rsa_key:
            try:
                # USE THE KEY TO VALIDATE THE JWT
                payload = jwt.decode(token,
                                     rsa_key,
                                     algorithms=ALGORITHMS,
                                     audience=API_AUDIENCE,
                                     issuer='https://' + AUTH0_DOMAIN + '/')

                return payload

            # Expired token
            except jwt.ExpiredSignatureError:
                raise AuthError(
                    {
                        'code': 'token_expired',
                        'description': 'Token expired.'
                    }, 401)
            # Token error in audience or issuer
            except jwt.JWTClaimsError:
                raise AuthError(
                    {
                        'code':
                        'invalid_claims',
                        'description':
                        'Incorrect claims. Please, check the audience and issuer.'
                    }, 401)
            # Catch any other exceptions that arise
            except Exception as e:
                traceback.print_exc()
                raise AuthError(
                    {
                        'code': 'invalid_header',
                        'description': 'Unable to parse authentication token.'
                    }, 400)
        # If no RSA key raise an auth error
        raise AuthError(
            {
                'code': 'invalid_header',
                'description': 'Unable to find the appropriate key.'
            }, 400)
    # Traceback is helping in debugging during dev
    except Exception as e:
        traceback.print_exc()
Esempio n. 37
0
def verify_decode_jwt(token):
    # print('In verify', token)
    jsonurl = urlopen(f'https://{AUTH0_DOMAIN}/.well-known/jwks.json')
    # print('After jsonurl')
    jwks = json.loads(jsonurl.read())
    # print('Before unverified header', jwks)
    unverified_header = jwt.get_unverified_header(token)

    rsa_key = {}
    # print('before if kid', unverified_header['kid'])
    if 'kid' not in unverified_header:
        raise AuthError(
            {
                'code': 'invalid_header',
                'description': 'Authorization malformed.'
            }, 401)

    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']
            }
    # print('Before rsa_key', rsa_key)
    if rsa_key:
        try:
            # print('Inside Try')
            payload = jwt.decode(token,
                                 rsa_key,
                                 algorithms=ALGORITHMS,
                                 audience=API_AUDIENCE,
                                 issuer='https://' + AUTH0_DOMAIN + '/')

            return payload

        except jwt.ExpiredSignatureError:
            raise AuthError(
                {
                    'code': 'token_expired',
                    'description': 'Token expired.'
                }, 401)

        except jwt.JWTClaimsError:
            raise AuthError(
                {
                    'code':
                    'invalid_claims',
                    'description':
                    'Incorrect claims. Please, check the audience and issuer.'
                }, 401)
        except Exception:
            raise AuthError(
                {
                    'code': 'invalid_header',
                    'description': 'Unable to parse authentication token.'
                }, 400)
    raise AuthError(
        {
            'code': 'invalid_header',
            'description': 'Unable to find the appropriate key.'
        }, 400)
Esempio n. 38
0
    def _get_user_info(self, access_token, id_token):
        """
        Extracts the user info payload from the Id Token.

        Example return value:

        {
            "at_hash": "<HASH>",
            "aud": "<HASH>",
            "email_verified": true,
            "email": "*****@*****.**",
            "exp": 1551259495,
            "family_name": "Surname",
            "given_name": "Firstname",
            "https://sso.mozilla.com/claim/groups": [
                "all_scm_level_1",
                "all_scm_level_2",
                "all_scm_level_3",
                # ...
            ],
            "iat": 1550654695,
            "iss": "https://auth.mozilla.auth0.com/",
            "name": "Firstname Surname",
            "nickname": "Firstname Surname",
            "nonce": "<HASH>",
            "picture": "<GRAVATAR_URL>",
            "sub": "ad|Mozilla-LDAP|fsurname",
            "updated_at": "2019-02-20T09:24:55.449Z",
        }
        """

        # JWT Validator
        # Per https://auth0.com/docs/quickstart/backend/python/01-authorization#create-the-jwt-validation-decorator

        try:
            unverified_header = jwt.get_unverified_header(id_token)
        except jwt.JWTError:
            raise AuthError('Unable to decode the Id token header')

        if 'kid' not in unverified_header:
            raise AuthError('Id token header missing RSA key ID')

        rsa_key = None
        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"]
                }
                break

        if not rsa_key:
            raise AuthError('Id token using unrecognised RSA key ID')

        try:
            # https://python-jose.readthedocs.io/en/latest/jwt/api.html#jose.jwt.decode
            user_info = jwt.decode(
                id_token,
                rsa_key,
                algorithms=['RS256'],
                audience=AUTH0_CLIENTID,
                access_token=access_token,
                issuer="https://"+AUTH0_DOMAIN+"/"
            )
            return user_info
        except jwt.ExpiredSignatureError:
            raise AuthError('Id token is expired')
        except jwt.JWTClaimsError:
            raise AuthError("Incorrect claims: please check the audience and issuer")
        except jwt.JWTError:
            raise AuthError("Invalid header: Unable to parse authentication")