def validate_bearer_token(bearer_token, secret_key): #print (bearer_token, secret_key) if not bearer_token: return None k = {"k": secret_key, "kty": "oct"} key = jwk.JWK(**k) try: bearer_token_l = bearer_token.split('Bearer') bearer_token = bearer_token_l[1].strip() ET = jwt.JWT(key=key, jwt=bearer_token) ST = jwt.JWT(key=key, jwt=ET.claims) # check_claims = required_token_claims) return json.loads(ST.claims) except jwt.JWTExpired: raise falcon.HTTPUnauthorized(description='Access Token Expired') except jwt.JWTInvalidClaimValue: raise falcon.HTTPUnauthorized( description='Invalid Token . Valid Token Claims are needed') except jwe.InvalidJWEData: raise falcon.HTTPUnauthorized( title="Invalid Data", description='Data Badly Encrypted. Please check key used.')
async def create_non_authenticated_jwt_tokens(): proof_of_possession_data = jwt.JWK.generate(kty='oct', size=256).export() proof_of_possession_token = jwt.JWT( header={'alg': 'RS256', 'kid': str(uuid.uuid4())}, claims=proof_of_possession_data ) proof_of_possession_token.make_signed_token(jwt_private_key) access_token_id = str(uuid.uuid4()) authorizations = await generate_generic_access_authorization() access_token = jwt.JWT( header={ 'alg': 'RS256', 'exp': (datetime.datetime.now() + datetime.timedelta(seconds=5)).timestamp(), 'iat': datetime.datetime.now().timestamp() }, claims={ 'cnf': {'dpop+jwt': proof_of_possession_token.serialize()}, 'iss': 'demo-server-1', **authorizations }) access_token.make_signed_token(jwt_private_key) access_token = jwt.JWT( header={"alg": "RSA-OAEP-256", "enc": "A256CBC-HS512", 'jti': access_token_id, 'typ': 'access'}, claims=access_token.serialize() ) access_token.make_encrypted_token(jwt_encrypting_public_key) return { 'key': proof_of_possession_token.serialize(), 'access': access_token.serialize(), }
def refresh(self): header = { 'alg': self.signing_algorithm, 'typ': 'JWT', } # normal(unencrypted) token token = jwt.JWT(header=header, claims=self.claims, check_claims=self.checked_claims, algs=self.ALLOWED_SIGNING_ALGORITHMS) token.make_signed_token(key=self.private_signing_key) self._normal = token.serialize() header = { 'alg': "ECDH-ES", 'enc': "A256GCM", } # header = settings.XAUTH.get('JWT_ENC_HEADERS', { # "alg": "A256KW", # "enc": "A256CBC-HS512", # }) # encrypted token e_token = jwt.JWT(header=header, claims=self.normal) e_token.make_encrypted_token(key=self.encryption_key) self._encrypted = e_token.serialize() return self.tokens
def test_valid_refresh(self): now = time.time() token = jwt.JWT( header={"alg": SIGNING_ALG}, claims={ "sub": self.urn, "use": "refresh", "iat": now }, ) token.make_signed_token(self.key) auth_headers = { "HTTP_AUTHORIZATION": f"Bearer {token.serialize()}", } response = self.client.post(reverse("identity:refresh"), **auth_headers) content = response.json() self.assertIsInstance(content, dict) found_access = jwt.JWT(key=self.key, jwt=content["access"]) access_claims = json.loads(found_access.claims) self.assertEqual(self.urn, access_claims["sub"]) self.assertEqual("access", access_claims["use"]) now = time.time() self.assertLessEqual(access_claims["iat"], now) self.assertGreaterEqual(access_claims["exp"], now)
def test_valid_attest(self): app = self.application auth_encoded = base64.b64encode( f"{app.client_id}:{app.client_secret}".encode("utf-8")) auth_headers = { "HTTP_AUTHORIZATION": f"Basic {auth_encoded.decode('utf-8')}", } response = self.client.post(reverse("identity:attest"), **auth_headers) content = response.json() self.assertIsInstance(content, dict) self.assertEqual(response.status_code, HTTPStatus.OK) expected_urn = "urn:pennlabs:test-application" access_jwt = jwt.JWT(key=self.key, jwt=content["access"]) refresh_jwt = jwt.JWT(key=self.key, jwt=content["refresh"]) access_claims = json.loads(access_jwt.claims) refresh_claims = json.loads(refresh_jwt.claims) self.assertEqual(expected_urn, access_claims["sub"]) self.assertEqual(expected_urn, refresh_claims["sub"]) self.assertEqual("access", access_claims["use"]) self.assertEqual("refresh", refresh_claims["use"]) now = time.time() self.assertLessEqual(access_claims["iat"], now) self.assertLessEqual(refresh_claims["iat"], now) self.assertGreaterEqual(access_claims["exp"], now) self.assertNotIn("exp", refresh_claims)
def test_asymmetric_jwe_token_plugin(self): plugin = JWTTokenApi("./tests/fixtures/private.pem") private_key = jwt.JWK() public_key = jwt.JWK() private_key_data = open("./tests/fixtures/private.pem", "rb").read() public_key_data = open("./tests/fixtures/public.pem", "rb").read() private_key.import_from_pem(private_key_data) public_key.import_from_pem(public_key_data) jwt_token = jwt.JWT({"alg": "RS256"}, { 'host': "remote_host", 'port': "remote_port" }) jwt_token.make_signed_token(private_key) jwe_token = jwt.JWT(header={ "alg": "RSA-OAEP", "enc": "A256CBC-HS512" }, claims=jwt_token.serialize()) jwe_token.make_encrypted_token(public_key) result = plugin.lookup(jwt_token.serialize()) self.assertIsNotNone(result) self.assertEqual(result[0], "remote_host") self.assertEqual(result[1], "remote_port")
def post(): # getting the inputs from request body request_object = request.get_json() username = request_object.get('username') token = request_object.get('token',None) url = request_object.get('url') # sanity checks if not url: return "420 Not all required parameters are passed" if not validators.url(url): return "415 unsupported media type" if not token: return "403 No JWT token present in request" _key = os.environ.get('Secret_Key') key = jwk.JWK(**json.loads(_key)) encrypted_token = jwt.JWT(key=key, jwt=token) signed_token = jwt.JWT(key=key, jwt=encrypted_token.claims) token_username = signed_token.claims['username'] if username != token_username: return "401 User is not authorized for the request" if not is_downloadable(url): return "415 unsupported Media Type." # downloading the image and sending the response thumbnail downloaded_image = requests.get(url) image = Image.open(BytesIO(downloaded_image.content)) thumbnail = image.resize((50,50), Image.ANTIALIAS) return thumbnail
def post(): request_object = request.get_json() username = request_object.get('username') password = request_object.get('password') payload = { 'username': username, } _key = os.environ.get('Secret_Key') key = jwk.JWK(**json.loads(_key)) # Creating an signed JWT token with JWK try: Token = jwt.JWT(header={"alg": "HS256"}, claims=payload) Token.make_signed_token(key) EToken = jwt.JWT(header={ "alg": "A256KW", "enc": "A256CBC-HS512" }, claims=Token.serialize()) EToken.make_encrypted_token(key) return EToken.serialize() except Exception as e: return "Token couldn't be generated. Please try again."
def __init__(self, agency, verifier, sub, name): logger.info("Initialize new request token") # compute the eligibility set for this token from agency and verifier eligibility = list(verifier.eligibility_set & agency.eligibility_set) # craft the main token payload payload = dict( jti=str(uuid.uuid4()), iss=ALLOWED_HOSTS[0], iat=int(datetime.datetime.utcnow().replace( tzinfo=datetime.timezone.utc).timestamp()), agency=agency.agency_id, eligibility=eligibility, sub=sub, name=name, ) logger.debug("Sign token payload with agency's private key") header = {"typ": "JWS", "alg": agency.jws_signing_alg} signed_token = jwt.JWT(header=header, claims=payload) signed_token.make_signed_token(agency.private_jwk) signed_payload = signed_token.serialize() logger.debug("Encrypt signed token payload with verifier's public key") header = { "typ": "JWE", "alg": verifier.jwe_encryption_alg, "enc": verifier.jwe_cek_enc } encrypted_token = jwt.JWT(header=header, claims=signed_payload) encrypted_token.make_encrypted_token(verifier.public_jwk) logger.info("Signed and encrypted request token initialized") self._jwe = encrypted_token
def test_asymmetric_jwe_token_plugin(self): private_key = jwt.JWK() public_key = jwt.JWK() private_key_data = open("./tests/fixtures/private.pem", "rb").read() public_key_data = open("./tests/fixtures/public.pem", "rb").read() private_key.import_from_pem(private_key_data) public_key.import_from_pem(public_key_data) jwt_token = jwt.JWT({"alg": "RS256"}, { 'host': "remote_host", 'port': "remote_port" }) jwt_token.make_signed_token(private_key) jwe_token = jwt.JWT(header={ "alg": "RSA1_5", "enc": "A256CBC-HS512" }, claims=jwt_token.serialize()) jwe_token.make_encrypted_token(public_key) self.handler.path = "https://localhost:6080/websockify?token={jwt_token}".format( jwt_token=jwe_token.serialize()) patcher = patch( 'websockify.websocketproxy.ProxyRequestHandler.send_auth_error' ).start() self.handler.server.token_plugin = token_plugins.JWTTokenApi( "./tests/fixtures/private.pem") self.handler.validate_connection() self.assertEqual(self.handler.server.target_host, "remote_host") self.assertEqual(self.handler.server.target_port, "remote_port")
def encrypt(self,**kwargs): values = kwargs["values"] key = self._get_key(**kwargs) secret = kwargs.get("secret") if not secret: secret = self._get_md5sum(key) header = kwargs.get("header",{"alg": "A256KW", "enc": "A256CBC-HS512"}) emessage = self._e_serialize(values,passphrase=secret) payload = {} payload["emessage"] = emessage _key = jwk.JWK(**key) _token = jwt2.JWT(header={"alg": self.algor}, claims=payload) _token.make_signed_token(_key) etoken = jwt2.JWT(header=header, claims=_token.serialize()) etoken.make_encrypted_token(_key) return etoken.serialize()
def patch(): # getting the inputs from request body request_object = request.get_json() username = request_object.get('username') token = request_object.get('token', None) json_object = request_object.get('json_object') json_patch_object = request_object.get('json_patch_object') # sanity checks if not json_object or not json_patch_object: return "420 Not all required parameters are passed" if not token: return "403 No JWT token present in request" _key = os.environ.get('Secret_Key') key = jwk.JWK(**json.loads(_key)) encrypted_token = jwt.JWT(key=key, jwt=token) signed_token = jwt.JWT(key=key, jwt=encrypted_token.claims) token_username = signed_token.claims['username'] if username != token_username: return "401 User is not authorized for the request" #Applying the patch and returning the result or if we get error it return 418 try: patch = jsonpatch.JsonPatch.from_string(json_patch_object) result = patch.apply(json_object) return result except InvalidJsonPatch: return "418 passed json patch object is invalid"
def verify_token(token): try: ET = jwt.JWT(key=key, jwt=token) ST = jwt.JWT(key=key, jwt=ET.claims) return ST.claims except: return False
def jwt_to_user_dictionary(jwtoken, jwt_key): try: key = jwk.JWK(**jwt_key) etoken = jwt.JWT(key=key, jwt=jwtoken) stoken = jwt.JWT(key=key, jwt=etoken.claims) return json.loads(stoken.claims) except jwe.InvalidJWEData: return {}
def get_user_id(token): e = token et = jwt.JWT(key=key, jwt=e) st = jwt.JWT(key=key, jwt=et.claims) parsed_json = json.loads(st.claims) return parsed_json['id']
def get_claims(self, token=None, encrypted: bool = __TOKEN_ENCRYPTED): token = self.encrypted if not token else token assert token is not None, "Call refresh() first or provide a token" token = token.decode() if isinstance(token, bytes) else token tk = jwt.JWT(key=self.encryption_key, jwt=u"%s" % token).claims if encrypted else token claims = jwt.JWT(key=self.public_signing_key, jwt=tk).claims return json.loads(claims)
def get_claims(token): if len(token) > 0: try: et = jwt.JWT(key=key, jwt=token) st = jwt.JWT(key=key, jwt=et.claims) return st.claims except Exception: return {} return {}
def verify_user(token): if len(token) > 0: try: et = jwt.JWT(key=key, jwt=token) jwt.JWT(key=key, jwt=et.claims) return True except Exception: return False return False
def test_A2(self): sigkey = jwk.JWK(**A2_example['key']) Touter = jwt.JWT(jwt=A2_token, key=E_A2_ex['key']) Tinner = jwt.JWT(jwt=Touter.claims, key=sigkey, check_claims=False) self.assertEqual(A1_claims, json_decode(Tinner.claims)) with self.assertRaises(jwe.InvalidJWEData): jwt.JWT(jwt=A2_token, key=E_A2_ex['key'], algs=['RSA_1_5', 'AES256GCM'])
def lookup(self, token): try: from jwcrypto import jwt import json key = jwt.JWK() try: with open(self.source, 'rb') as key_file: key_data = key_file.read() except Exception as e: print("Error loading key file: %s" % str(e), file=sys.stderr) return None try: key.import_from_pem(key_data) except: try: key.import_key(k=key_data.decode('utf-8'), kty='oct') except: print('Failed to correctly parse key data!', file=sys.stderr) return None try: token = jwt.JWT(key=key, jwt=token) parsed_header = json.loads(token.header) if 'enc' in parsed_header: # Token is encrypted, so we need to decrypt by passing the claims to a new instance token = jwt.JWT(key=key, jwt=token.claims) parsed = json.loads(token.claims) if 'nbf' in parsed: # Not Before is present, so we need to check it if time.time() < parsed['nbf']: print('Token can not be used yet!', file=sys.stderr) return None if 'exp' in parsed: # Expiration time is present, so we need to check it if time.time() > parsed['exp']: print('Token has expired!', file=sys.stderr) return None return (parsed['host'], parsed['port']) except Exception as e: print("Failed to parse token: %s" % str(e), file=sys.stderr) return None except ImportError as e: print( "package jwcrypto not found, are you sure you've installed it correctly?", file=sys.stderr) return None
def test_A1(self): key = jwk.JWK(**E_A2_key) # first encode/decode ourselves T = jwt.JWT(A1_header, A1_claims) T.make_encrypted_token(key) token = T.serialize() T.deserialize(token) # then try the test vector T = jwt.JWT(jwt=A1_token, key=key, check_claims=False) # then try the test vector with explicit expiration date T = jwt.JWT(jwt=A1_token, key=key, check_claims={'exp': 1300819380}) # Finally check it raises for expired tokens self.assertRaises(jwt.JWTExpired, jwt.JWT, jwt=A1_token, key=key)
def decrypt(self,**kwargs): etoken = kwargs["token"] key = self._get_key(**kwargs) secret = kwargs.get("secret",self._get_md5sum(key)) _key = jwk.JWK(**key) ET = jwt2.JWT(key=_key,jwt=etoken) ST = jwt2.JWT(key=_key,jwt=ET.claims) emessage = eval(ST.claims)["emessage"] return self._de_serialize(emessage,passphrase=secret,convert2json=True)
def get_user_from_token(token): try: if not token: return 'Token access is required', 400 name = ast.literal_eval(jwt.JWT(key=key, jwt=token).claims).get('username') if not name: name = ast.literal_eval(jwt.JWT(key=key, jwt=token).claims).get('platform') return name, 200 except: return 'No valid Token given', 400
def generate_encrypted_token(self, key, claims): token = jwt.JWT(header={"alg": "HS256"}, claims=claims) #sign token token.make_signed_token(key) #encrypt token etoken = jwt.JWT(header={ "alg": "A256KW", "enc": "A256CBC-HS512" }, claims=token.serialize()) etoken.make_encrypted_token(key) return etoken.serialize()
def test_public_key_verification(): '''Ensure that anything that was signed with the private key can be verify by the public key ''' payload = {'user_id': 123} # Generated signed jwt token jwt_obj = jwt.JWT(header={"alg": "RS256"}, claims={'user_id': 123}) jwt_obj.make_signed_token(jwk.JWK.from_json(config.Config.JWK_PRIVATE)) signed_jwt_token = jwt_obj.serialize() # Deconstruct the signed jwt token by decrypting it with the public key deconstructed_jwt_token = jwt.JWT(key=jwk.JWK.from_json( config.Config.JWK_PUBLIC), jwt=signed_jwt_token) assert json.loads(deconstructed_jwt_token.claims) == payload
def test_auth_verify_bearer_expired_token(self): settings = get_settings() keyset = get_keyset() kid = "2aedafba-8170-4064-b704-ce92b7c89cc6" key = keyset.get_key(kid) exp_time = round(time.time()) - 1000 for user_id_field in settings['USER_ID_FIELDS']: token = jwt.JWT(header={ "kid": kid, "alg": "ES256" }, claims={ 'exp': exp_time, user_id_field: '*****@*****.**' }) token.make_signed_token(key) bearer = 'Bearer {}'.format(token.serialize()) with self.assertRaises(AuthenticationFailed) as cm: decoded_claims, user_id = JWTAccessToken.token_data( bearer, True) e = cm.exception self.assertTrue( str(e).startswith('API authz problem: token expired'))
def deserialize_verify(self, model: Type[Payload], public_key: str): """Attempt to deserialize and verify the JWT's signature. Then against the claims in a given payload model""" key = jwk.JWK.from_pem(data=public_key.encode("utf-8")) t = jwt.JWT(key=key, jwt=self.token, algs=["RS256"]) return model.parse_raw(t.claims)
def auth(event, context): bodyTemplate = '[{0}] {1} ({2})' try: # retrieve cookie from requester token = event['headers']['X-rft-gs-authorization'] # verify that the token with open('auth/key.json', 'rb') as file: key = jwk.JWK(**json.loads(file.read())) verified = jwt.JWT(key=key, jwt=token) except KeyError as e: raise Exception(bodyTemplate.format(401, 'Unauthorized: no session cookie found', str(e))) except (jwk.InvalidJWKValue, jwk.InvalidJWKOperation, jwk.InvalidJWKUsage, jws.InvalidJWSSignature, jws.InvalidJWSObject, jws.InvalidJWSOperation) as e: raise Exception(bodyTemplate.format(401, 'Unauthorized: token not valid', str(e))) except ClientError as e: raise Exception(bodyTemplate.format(401, 'Unauthorized: table entry not valid', str(e))) except: raise Exception(bodyTemplate.format(401, 'Unauthorized: unknown error', 'token=' + str(token) + ' event=' + str(event))) raise Exception(bodyTemplate.format(202, 'Authorized: welcome!', str(verified.claims)))
def _make_token(self, payload): """Wrap payload in a signed and encrypted JWT for response.""" # sign the payload with server's private key header = {"typ": "JWS", "alg": self.db.jws_signing_alg} signed_token = jwt.JWT(header=header, claims=payload) signed_token.make_signed_token(server_private_key) signed_payload = signed_token.serialize() # encrypt the signed payload with client's public key header = { "typ": "JWE", "alg": self.db.jwe_encryption_alg, "enc": self.db.jwe_cek_enc } encrypted_token = jwt.JWT(header=header, claims=signed_payload) encrypted_token.make_encrypted_token(client_public_key) return encrypted_token.serialize()
def PolishApiRequest(target, json_request): request_id = getUUID() json_string = json.dumps(json_request) filename = f"{request_id}.json" with open(filename, "w") as f: json.dump(json_request, f) key = open("private.pem", "rb").read() key = jwk.JWK().from_pem(key) Token = jwt.JWT(header=getHeaders(), claims=json_string) Token.make_signed_token(key) Token.serialize() encoded_jwt = Token.serialize() jwt_split = encoded_jwt.split(".") jwt_split[1] = "" sign = ".".join(jwt_split) request = f"curl -X POST \"{target}\" -k --key private.pem --cert qwac_pub.pem -H \"accept: application/json\" -H \"Accept-Encoding: gzip\" -H \"Accept-Language: pl_PL\" -H \"Accept-Charset: utf-8\" -H \"X-JWS-SIGNATURE: {sign}\" -H \"X-REQUEST-ID: {request_id}\" -H \"Content-Type: application/json\" -d @{request_id}.json --output - | gunzip" result = os.popen(request).read().strip() os.remove(filename) return result