def test_certs_dict(self): jwt.decode( firebase_token, firebase_certs, algorithms='RS256', options={'verify_exp': False, 'verify_aud': False} )
def test_individual_cert(self): jwt.decode( firebase_token, firebase_certs["f4b0a5c73ad85a5da09f0e7f76463631339e0bbf"], algorithms='RS256', options={'verify_exp': False, 'verify_aud': False} )
def test_certs_string(self): certs = json.dumps(firebase_certs) jwt.decode( firebase_token, certs, algorithms='RS256', options={'verify_exp': False, 'verify_aud': False} )
def test_iss_tuple(self, key): iss = 'issuer' claims = { 'iss': iss } token = jwt.encode(claims, key) jwt.decode(token, key, issuer=('https://issuer', 'issuer'))
def test_sub_correct(self, key): sub = 'subject' claims = { 'sub': sub } token = jwt.encode(claims, key) jwt.decode(token, key, subject=sub)
def test_nbf_datetime(self, key): nbf = datetime.utcnow() - timedelta(seconds=5) claims = { 'nbf': nbf } token = jwt.encode(claims, key) jwt.decode(token, key)
def test_exp_datetime(self, key): exp = datetime.utcnow() + timedelta(seconds=5) claims = { 'exp': exp } token = jwt.encode(claims, key) jwt.decode(token, key)
def test_aud_string(self, key): aud = 'audience' claims = { 'aud': aud } token = jwt.encode(claims, key) jwt.decode(token, key, audience=aud)
def test_aud_list(self, key): aud = 'audience' claims = { 'aud': [aud] } token = jwt.encode(claims, key) jwt.decode(token, key, audience=aud)
def test_aud_list_multiple(self, key): aud = 'audience' claims = { 'aud': [aud, 'another'] } token = jwt.encode(claims, key) jwt.decode(token, key, audience=aud)
def test_iss_string(self, key): iss = 'issuer' claims = { 'iss': iss } token = jwt.encode(claims, key) jwt.decode(token, key, issuer=iss)
def test_sub_string(self, key): sub = 'subject' claims = { 'sub': sub } token = jwt.encode(claims, key) jwt.decode(token, key)
def test_jti_string(self, key): jti = 'JWT ID' claims = { 'jti': jti } token = jwt.encode(claims, key) jwt.decode(token, key)
def test_iss_list(self, key): iss = 'issuer' claims = { 'iss': iss } token = jwt.encode(claims, key) jwt.decode(token, key, issuer=['https://issuer', 'issuer'])
def test_iat_not_int(self, key): claims = { 'iat': 'test' } token = jwt.encode(claims, key) with pytest.raises(JWTError): jwt.decode(token, key)
def test_require(self, claims, key, claim, value): options = {"require_" + claim: True, "verify_" + claim: False} token = jwt.encode(claims, key) with pytest.raises(JWTError): jwt.decode(token, key, options=options, audience=str(value)) new_claims = dict(claims) new_claims[claim] = value token = jwt.encode(new_claims, key) jwt.decode(token, key, options=options, audience=str(value))
def test_jti_invalid(self, key): jti = 1 claims = { 'jti': jti } token = jwt.encode(claims, key) with pytest.raises(JWTError): jwt.decode(token, key)
def test_sub_incorrect(self, key): sub = 'subject' claims = { 'sub': sub } token = jwt.encode(claims, key) with pytest.raises(JWTError): jwt.decode(token, key, subject='another')
def test_aud_case_sensitive(self, key): aud = 'audience' claims = { 'aud': [aud] } token = jwt.encode(claims, key) with pytest.raises(JWTError): jwt.decode(token, key, audience='AUDIENCE')
def test_aud_list_is_strings(self, key): aud = 'audience' claims = { 'aud': [aud, 1] } token = jwt.encode(claims, key) with pytest.raises(JWTError): jwt.decode(token, key, audience=aud)
def test_aud_not_string_or_list(self, key): aud = 1 claims = { 'aud': aud } token = jwt.encode(claims, key) with pytest.raises(JWTError): jwt.decode(token, key)
def test_aud_given_number(self, key): aud = 'audience' claims = { 'aud': aud } token = jwt.encode(claims, key) with pytest.raises(JWTError): jwt.decode(token, key, audience=1)
def test_iss_invalid(self, key): iss = 'issuer' claims = { 'iss': iss } token = jwt.encode(claims, key) with pytest.raises(JWTError): jwt.decode(token, key, issuer='another')
def test_sub_invalid(self, key): sub = 1 claims = { 'sub': sub } token = jwt.encode(claims, key) with pytest.raises(JWTError): jwt.decode(token, key)
def test_nbf_in_future(self, key): nbf = datetime.utcnow() + timedelta(seconds=5) claims = { 'nbf': nbf } token = jwt.encode(claims, key) with pytest.raises(JWTError): jwt.decode(token, key)
def test_exp_in_past(self, key): exp = datetime.utcnow() - timedelta(seconds=5) claims = { 'exp': exp } token = jwt.encode(claims, key) with pytest.raises(JWTError): jwt.decode(token, key)
def test_nbf_with_leeway(self, key): nbf = datetime.utcnow() + timedelta(seconds=5) claims = { 'nbf': nbf, } options = { 'leeway': 10 } token = jwt.encode(claims, key) jwt.decode(token, key, options=options)
def test_exp_with_leeway(self, key): exp = datetime.utcnow() - timedelta(seconds=5) claims = { 'exp': exp, } options = { 'leeway': 10 } token = jwt.encode(claims, key) jwt.decode(token, key, options=options)
def test_invalid_claims(self): old_jws_verify = jws.verify try: token = u'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhIjoiYiJ9.jiMyrsmD8AoHWeQgmxZ5yq8z0lXS67_QGs52AzC8Ru8' def return_encoded_array(token, key, algorithms, verify=True): return b'["a","b"]' jws.verify = return_encoded_array with pytest.raises(JWTError, match='Invalid payload string: must be a json object'): jwt.decode(token, 'secret', ['HS256']) finally: jws.verify = old_jws_verify
def test_leeway_is_timedelta(self, claims, key): nbf = datetime.utcnow() + timedelta(seconds=5) leeway = timedelta(seconds=10) claims = { 'nbf': nbf, } options = { 'leeway': leeway } token = jwt.encode(claims, key) jwt.decode(token, key, options=options)
def decorated(*args, **kwargs): try: token = get_token_auth_header() print(token) jsonurl = urlopen("https://login.microsoftonline.com/" + TENANT_ID + "/discovery/v2.0/keys") 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"] } except Exception: print("THIS ONE") raise AuthError( { "code": "invalid_header", "description": "Unable to parse authentication" " token." }, 401) if rsa_key: try: payload = jwt.decode( token, rsa_key, algorithms=["RS256"], # audience=API_AUDIENCE, issuer="https://sts.windows.net/" + TENANT_ID + "/") 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: print("THIS ONE 2") raise AuthError( { "code": "invalid_header", "description": "Unable to parse authentication" " token." }, 401) _request_ctx_stack.top.current_user = payload # print(_request_ctx_stack.top.current_user) return f(*args, **kwargs) raise AuthError( { "code": "invalid_header", "description": "Unable to find appropriate key" }, 401)
def test_non_default_alg_positional_bwcompat(self, claims, key): encoded = jwt.encode(claims, key, 'HS384') decoded = jwt.decode(encoded, key, 'HS384') assert claims == decoded
def test_aud_empty_claim(self, claims, key): aud = 'audience' token = jwt.encode(claims, key) jwt.decode(token, key, audience=aud)
def decode_token(token: str): """Return a dictionary that represents the decoded JWT. """ return jwt.decode(token, settings.SECRET_KEY, algorithms=[ALGORITHM])
def verify_decode_jwt(token: str): """ Return the decoded JWT payload. Input: Json Web Token (Auth0 token with key id (kid)) Verify the token using Auth0 /.well-known/jwks.json decode the payload from the token, validate the claims, !!NOTE urlopen has a common certificate error described here: https://stackoverflow.com/questions/50236117/scraping-ssl-certificate-verify-failed-error-for-http-en-wikipedia-org """ # Get the public key from Auth0 json_url = urlopen(f'https://{AUTH0_DOMAIN}/.well-known/jwks.json') jwks = json.loads(json_url.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'] } 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)
def verify_token(token, key): try: token = jwt.decode(token, key, audience="ow:key", algorithms=['HS256']) except JWTError as e: token = e return token
def check_secret(api_key, api_secret): decoded = jwt.decode(api_secret, ApiSecretField.secret, algorithms=['HS256']) return decoded.get('key') == api_key
def decode_jwt(token): try: return jwt.decode(token, settings.SECRET_KEY, algorithms=[ALGO]) except jwt.JWTError: return None
def verify_decode_jwt(token): jsonurl = urlopen(f'http://{AUTH0_DOMAIN}/.well-known/jwks.json') jwks = json.loads(jsonurl.read()) header = jwt.get_unverified_header(token) # check if kid in header if 'kid' in header: if header['kid']: rsa_key = {} for key in jwks['keys']: # if kid in jwks matches the rsa key will be created if key['kid'] == header['kid']: rsa_key = { 'kty': key['kty'], 'kid': key['kid'], 'use': key['use'], 'n': key['n'], 'e': key['e'] } if rsa_key: try: # create the payload payload = jwt.decode(token, rsa_key, algorithms=ALGORITHMS, audience=API_AUDIENCE, issuer='https://' + AUTH0_DOMAIN + '/') return payload except jwt.JWTClaimsError: raise AuthError( { 'code': 'the claims are invalid', 'description': 'please check the audience and issuer.' }, 401) # exception if the token expired except jwt.ExpiredSignatureError: raise AuthError( { 'code': 'token has expired', 'description': 'token expired' }, 401) # exception in case of any error except Exception: raise AuthError( { 'code': 'invalid_header', 'description': 'Unable to parse authentication token.' }, 400) else: raise AuthError( { 'code': 'invalid_header', 'description': 'Authorization malformed' }, 401) else: raise AuthError( { 'code': 'invalid_header', 'description': 'Unable to find the ke1722' }, 400)
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")
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. Check 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)
def verify_decode_jwt(token): # get the public key from Auth0 # verify the token using Auth0 /.well-known/jwks.json 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: print('not kid') 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'] } # use the key to validate the jwt if rsa_key: try: # decode the payload from the token 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: print('5') 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)
def verify_decode_jwt(token): ''' verify the given auth0 token using Auth0 /.well-known/jwks.json decode the payload from the token validate the claims return the decoded payload @INPUTS token: a json web token (string) ''' 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)
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 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.' }, 401) except jwt.JWTError: raise AuthError( { 'code': 'invalid signature', 'description': 'the signature is invalid in some way' }, 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)
def verify_token(token: str, jwks: dict, issuer: str) -> dict: try: unverified_header = jwt.get_unverified_header(token) except jwt.JWTError: raise AuthError( { "code": "invalid_header", "description": "Unable to parse authentication token.", }, 401, ) rsa_key: Dict[str, str] = {} 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=["RS256"], audience="account", issuer=issuer, ) 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 payload raise AuthError( { "code": "invalid_header", "description": "Unable to find appropriate key.", }, 401, )
def verify_decode_jwt(token): # GET THE PUBLIC KEY FROM AUTH0 try: jsonurl = urlopen("https://" + AUTH0_DOMAIN + "/.well-known/jwks.json") jwks = json.loads(jsonurl.read()) except: abort(401) #non existent user try: unverified_header = jwt.get_unverified_header(token) except: abort(401) # Wrong signature rsa_key = {} for key in jwks["keys"]: try: key["kid"] unverified_header["kid"] except: abort(401) 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: abort(401) #Token is expiered raise AuthError( { "code": "token_expired", "description": "token is expired" }, 401) except jwt.JWTClaimsError: abort(401) raise AuthError( { "code": "invalid_claims", "description": "incorrect claims," "please check the audience and issuer" }, 401) except jwt.JWTClaimsError: raise AuthError( { "code": "invalid_claims", "description": "incorrect claims," "please check the audience and issuer" }, 401) except Exception: abort(401) 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)
def decorated(*args, **kwargs): """ The decorator requiring authentication before func may be called. """ 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_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=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 func(*args, **kwargs) raise AuthError( { "code": "invalid_header", "description": "Unable to find appropriate key" }, 401)
def test_at_hash_missing_claim(self, claims, key): token = jwt.encode(claims, key) with pytest.raises(JWTError): jwt.decode(token, key, access_token='<ACCESS_TOKEN>')
def decode(encoded_token): return jose_jwt.decode(encoded_token, current_app.config['SECRET_KEY'], algorithms=current_app.config['JWT_ALGORITHM'])
def test_at_hash_invalid(self, claims, key): token = jwt.encode(claims, key, access_token='<ACCESS_TOKEN>') with pytest.raises(JWTError): jwt.decode(token, key, access_token='<OTHER_TOKEN>')
def verify_password_reset_token(token: str) -> Optional[str]: try: decoded_token = jwt.decode(token, settings.SECRET_KEY, algorithms=["HS256"]) return decoded_token["email"] except jwt.JWTError: return None
def decode_token(token): return jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
def verify_decode_jwt(token): # most of the code in this method was # derived from the lectures and examples # get key from auth0 jsonurl = urlopen(f'https://{AUTH0_DOMAIN}/.well-known/jwks.json') jwks = json.loads(jsonurl.read()) # get header unverified_header = jwt.get_unverified_header(token) # choose 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 if rsa_key: try: # use key to validate 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': 'Invalid claims. 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)
def test_at_hash(self, claims, key): access_token = '<ACCESS_TOKEN>' token = jwt.encode(claims, key, access_token=access_token) payload = jwt.decode(token, key, access_token=access_token) assert 'at_hash' in payload
def decode_token(self, token): return jwt.decode(token, self.signing_key, algorithms=[self.signing_key_alg], audience=self.audience, issuer=self.issuer)
def test_at_hash_unable_to_calculate(self, claims, key): token = jwt.encode(claims, key, access_token='<ACCESS_TOKEN>') with pytest.raises(JWTError): jwt.decode(token, key, access_token='\xe2')
def _validate_jwt(self, token): jwt.decode(token, self.key, algorithms=['ES384'], audience='capnp') return True
def verify_decode_jwt(token): # Check for key id (kid) unverified_header = jwt.get_unverified_header(token) if 'kid' not in unverified_header: raise AuthError( { 'code': 401, 'description': 'No key ID: authorization is malformed' }, 401) # Verify the token using Auth0 /.well-known/jwks.json domain_url = 'https://%s/.well-known/jwks.json' % (AUTH0_DOMAIN) jsonurl = urlopen(domain_url) content = jsonurl.read().decode(jsonurl.headers.get_content_charset()) jwks = json.loads(content) 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: 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)
def test_non_default_alg(self, claims, key): encoded = jwt.encode(claims, key, algorithm='HS384') decoded = jwt.decode(encoded, key, algorithms='HS384') assert claims == decoded
def decode_token(token: str): payload = jwt.decode(token, JWT_SECRET, algorithms=JWT_ALGORITHM) return payload