def _get_userinfo(self, *args, **kwargs): info = self.cfg.datastore.getUserInfo(self.api_token['userinfocode']) if not info: return self._respond_error('invalid_request', 'No userinfo for token') if self.api_client.get('userinfo_signed_response_alg'): cherrypy.response.headers.update({ 'Content-Type': 'application/jwt' }) if self.api_client.get('userinfo_signed_response_alg') == 'RS256': sig = JWT(header={'alg': 'RS256', 'kid': self.cfg.idp_sig_key_id}, claims=info) else: return self._respond_error( 'unsupported_response_type', 'Requested signing mech not supported') # FIXME: Maybe add other algorithms in the future sig.make_signed_token(self.cfg.keyset.get_key( self.cfg.idp_sig_key_id)) # FIXME: Maybe encrypt in the future info = sig.serialize(compact=True) if isinstance(info, dict): info = json.dumps(info) return info
def client_assertion(self, audience: str, lifetime: int = 60, jti: str = None) -> str: iat = int(datetime.now().timestamp()) exp = iat + lifetime if jti is None: jti = str(uuid4()) elif callable(jti): jti = jti() if not isinstance(jti, str): jti = str(jti) jwt = JWT( header={ "alg": self.alg, "kid": self.kid }, claims={ "iss": self.client_id, "sub": self.client_id, "aud": audience, "iat": iat, "exp": exp, "jti": jti, }, ) jwt.make_signed_token(self.private_jwk) assertion: str = jwt.serialize() return assertion
def _get_metadata() -> Tuple[Dict[str, Any], str]: """Download the metadata TOC.""" try: metadata = requests.get( SETTINGS.metadata_service['url'], params={'token': SETTINGS.metadata_service['access_token']}, timeout=SETTINGS.metadata_service['timeout']) except requests.exceptions.RequestException: raise CommandError('MDS response error.') # First, we decode the unverified headers to get the certificate try: decoded_jwt = JWT(jwt=metadata.content.decode()) except ValueError: raise CommandError('MDS response malformed.') # x5c element in header contains the signing certificate and possibly intermediate certificates # Use the first one to verify signature, the others can be used to verify the first one try: decoding_key = verify_certificate(decoded_jwt) except InvalidCert: raise CommandError('Could not read the key.') try: decoded_jwt.deserialize(metadata.content.decode(), key=decoding_key) except InvalidJWSSignature: raise CommandError('Could not verify MDS signature.') # Return parsed metadata and the algorith for signing return json.loads(decoded_jwt.claims), json.loads( decoded_jwt.header)['alg']
def setUpAuthorization(self): """ SET token_scope_hr to use with: self.client.credentials( HTTP_AUTHORIZATION='Bearer {}'.format(self.token_scope_hr)) """ jwks = get_keyset() assert len(jwks['keys']) > 0 key = next(iter(jwks['keys'])) now = int(time.time()) headers = { 'alg': 'ES256', # algorithm of the test key 'kid': key.key_id } payload = { 'iat': now, 'exp': now + 600, 'scopes': [settings.SCOPE_HR_R] } token = JWT(header=headers, claims=payload) token.make_signed_token(key) self.token_scope_hr_r = token.serialize()
def _get_token(self, scope): """ Obtain a token to be used in the http client: self.client.credentials( HTTP_AUTHORIZATION='Bearer {}'.format(token)) """ jwks = get_keyset() assert len(jwks["keys"]) > 0 key = next(iter(jwks["keys"])) now = int(time.time()) header = {"alg": "ES256", "kid": key.key_id} # algorithm of the test key token = JWT( header=header, claims={ "iat": now, "exp": now + 600, "scopes": [scope], }, ) token.make_signed_token(key) return token.serialize()
def make_sig_kem(name, value, key, alg): header = {"kid": key.key_id, "alg": alg} claims = {"sub": name, "exp": int(time.time() + (5 * 60))} if value is not None: claims["value"] = value S = JWT(header, claims) S.make_signed_token(key) return S.serialize(compact=True)
def make_sig_kem(name, value, key, alg): header = {'kid': key.key_id, 'alg': alg} claims = {'sub': name, 'exp': int(time.time() + (5 * 60))} if value is not None: claims['value'] = value jwt = JWT(header, claims) jwt.make_signed_token(key) return jwt.serialize(compact=True)
def verify(self, key=None): jwt = JWT() jwt.deserialize(self.serialize()) jws = jwt.token if not key: tprint = jws.jose_header["kid"] key = keystore()[tprint] jws.verify(key)
def create_signed_token(claims, jwk=get_jwk()): if jwk is None: return None token = JWT(header={"alg": "HS256"}, claims=claims) token.make_signed_token(jwk) return token
def decrypt_jwt(jwt, jwk=get_jwk()): if jwk is None: return None encrypted_token = JWT(key=jwk, jwt=jwt) signed_token = JWT(key=jwk, jwt=encrypted_token.claims) return json.loads(signed_token.claims)
def _fetcher(scopes): kid = "2aedafba-8170-4064-b704-ce92b7c89cc6" key = jwks.get_keyset().get_key(kid) token = JWT(header={ "alg": "ES256", "kid": kid }, claims=fetch_tokendata(scopes)) token.make_signed_token(key) return token.serialize()
async def decode_claims(self, token: str) -> "JWTClaims": from jwcrypto.jwt import JWT LOG.debug("Verifying token: %r", token) jwt = JWT(jwt=token) key = jwt.token.jose_header["kid"] await self.get_key(key) jwt = JWT(jwt=token, key=self.keys) return json.loads(jwt.claims)
def _fromSerialization(BlockClass, serialized, chain): jwt = JWT() jwt.deserialize(serialized) jws = jwt.token block_json = json.loads(str(jws.objects["payload"], "utf8")) block = BlockClass.deserialize(block_json, jws.jose_header["kid"], chain) block._serialization = serialized return block
def jwt_token(self, scope): now = int(time.time()) scopes = [scope] if isinstance(scope, str) else [] payload = {'iat': now, 'exp': now + 300, 'scopes': scopes} headers = { 'alg': 'ES256', # algorithm of the test key 'kid': self.kid } token = JWT(header=headers, claims=payload) token.make_signed_token(self.key) return token.serialize()
def _serialize(self): """Performs the serialization but the object is not "frozen" by setting ``_serialization``. """ h = { "alg": "ES256", "kid": thumbprint(self._key), } jwt = JWT(header=h, claims=self.toJson()) jwt.make_signed_token(self._key) log.debug("Block signed with key thumbprint: {}".format(h["kid"])) return jwt.serialize()
def create_encrypted_token(claims, jwk=get_jwk()): signed_jwt = create_signed_jwt(claims, jwk) encrypted_token = JWT(header={ "alg": "A256KW", "enc": "A256CBC-HS512" }, claims=signed_jwt) encrypted_token.make_encrypted_token(jwk) return encrypted_token
def test_1_Parse_GET(self): cli_skey = JWK(**self.client_keys[0]) jtok = make_sig_kem("mykey", None, cli_skey, "RS256") kem = KEMHandler({'KEMKeysStore': self.kk}) kem.parse(jtok, "mykey") out = kem.reply('output') jtok = JWT(jwt=json_decode(out)['value']) cli_ekey = JWK(**self.client_keys[1]) jtok.token.decrypt(cli_ekey) nested = jtok.token.payload jtok = JWT(jwt=nested.decode('utf-8')) jtok.token.verify(JWK(**test_keys[0])) payload = json_decode(jtok.token.payload)['value'] self.assertEqual(payload, 'output')
def test_malformed_key(self): token = 'eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsIng1YyI6WyJhYWFhYWFhIl19.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikp' \ 'vaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.Dvmv1EMeu-pAqJdJAIXKef6M_Kx2Dn2qCLZyBF63f3RcI1ddDCXADlLmwvMjCX7u' \ 'V1R5AbLMf_rLxUlGZZnXvg' jwt = JWT(jwt=token) with self.assertRaises(InvalidCert): verify_certificate(jwt)
def set_user_jwt(auth_key, profile): """ Logs in (or signs up) a new user given its JWT and a default profile """ # Load the most current keys from Redis jwkeys.import_keyset(redis_db.get('jwkeys')) try: jwt = JWT(jwt=auth_key, key=jwkeys) claims = json_loads(jwt.claims) except: # This is called if the authorization failed (auth key has been forged) # We don't really care about providing malicious requests with debug # info so this is just a really basic error message return render_error('rejected.'), 403 # JWT has a couple of fields (claims) that we care about: # - iss: Issuer - Basically provider of open id (google, SE, etc.) # - sub: Subject - Who is auth'd by this. # Together we will use these to store an auth method. issuer = claims.get('iss') subject = claims.get('sub') # Error handle against malformed keys. This should never really happen and # the error is not shown to the user so doesn't need to be user-friendly if not issuer or not subject: return render_error('malformed. Missing iss or sub'), 400 # If we are here that means we have validated a valid login attempt. Now we # will delegate to another method token = UserJWTToken(identity=subject, issuer=issuer) return get_or_set_user(jwt_token=token, profile=profile)
def create_secure_metadata(key_id, key_secret, expires, metadata): header = { "alg": "dir", "enc": "A256GCM", "kid": key_id, } claims = { "exp": int(expires), "ninchat.com/metadata": metadata, } key = JWK(kty="oct", k=key_secret) token = JWT(header=header, claims=claims) token.make_encrypted_token(key) return token.serialize()
def expiration_datetime_from_jwt_token(jwt_token: str, jwt_secret: str) -> datetime: key = JWK(kty='oct', k=jwt_secret) jwt = JWT(jwt=jwt_token, key=key) jwt_claims_json = jwt.claims claims = json.loads(jwt_claims_json) expiration_datetime = datetime.datetime.fromtimestamp(claims['exp']) return expiration_datetime
def create_webpush_jwt(endpoint_url): with open(WEBPUSH_PRIVATE_KEY_PATH, 'rb') as key: jwk = JWK.from_pem(key.read()) jwt = JWT(header={ 'typ': 'JWT', 'alg': 'ES256' }, claims={ 'sub': f'mailto:{notifications["support_email"]}', 'exp': str(int(time() + WEBPUSH_EXPIRATION)), 'aud': f'{endpoint_url.scheme}://{endpoint_url.netloc}' }, algs=['ES256']) jwt.make_signed_token(jwk) return jwt.serialize()
def create_apns_jwt(): with open(path.join(getcwd(), APNS_KEY), 'rb') as key: jwk = JWK.from_pem(key.read()) jwt = JWT(header={ 'typ': 'JWT', 'alg': 'ES256', 'kid': notifications['apns_key_id'] }, claims={ 'iss': notifications['apple_team_id'], 'iat': int(time()) }, algs=['ES256']) jwt.make_signed_token(jwk) return jwt.serialize()
def make_idtoken(client, claims): '''Make a serialized JWT targeted for this client''' if client.idtoken_algo == client.ALGO_HMAC: header = {'alg': 'HS256'} jwk = JWK(kty='oct', k=base64url(client.client_secret.encode('utf-8'))) elif client.idtoken_algo == client.ALGO_RSA: header = {'alg': 'RS256'} jwk = get_first_rsa_sig_key() header['kid'] = jwk.key_id if jwk is None: raise ImproperlyConfigured( 'no RSA key for signature operation in A2_IDP_OIDC_JWKSET') else: raise NotImplementedError jwt = JWT(header=header, claims=claims) jwt.make_signed_token(jwk) return jwt.serialize()
def handle(self, *args: str, **options: Any) -> None: """Main function of this command. It creates a JWT test token with the provided scopes and validity. """ key = JWK(**json.loads(settings.JWKS_TEST_KEY)["keys"][0]) scopes = list(set(args)) now = int(time.time()) claims = { "iat": now, "exp": now + options["valid"], "scopes": scopes, "sub": "*****@*****.**", } token = JWT(header={"alg": "ES256", "kid": key.key_id}, claims=claims) token.make_signed_token(key) sys.stdout.write(token.serialize()) sys.stdout.write("\n")
def parse(self, msg, name): """Parses the message. We check that the message is properly formatted. :param msg: a json-encoded value containing a JWS or JWE+JWS token :raises InvalidMessage: if the message cannot be parsed or validated :returns: A verified payload """ try: jtok = JWT(jwt=msg) except Exception as e: raise InvalidMessage('Failed to parse message: %s' % str(e)) try: token = jtok.token if isinstance(token, JWE): token.decrypt(self.kkstore.server_keys[KEY_USAGE_ENC]) # If an encrypted payload is received then there must be # a nested signed payload to verify the provenance. payload = token.payload.decode('utf-8') token = JWS() token.deserialize(payload) elif isinstance(token, JWS): pass else: raise TypeError("Invalid Token type: %s" % type(jtok)) # Retrieve client keys for later use self.client_keys = [ JWK(**self._get_key(token.jose_header, KEY_USAGE_SIG)), JWK(**self._get_key(token.jose_header, KEY_USAGE_ENC)) ] # verify token and get payload token.verify(self.client_keys[KEY_USAGE_SIG]) claims = json_decode(token.payload) except Exception as e: logger.debug('Failed to validate message', exc_info=True) raise InvalidMessage('Failed to validate message: %s' % str(e)) check_kem_claims(claims, name) self.name = name self.payload = claims.get('value') self.msg_type = 'kem' return { 'type': self.msg_type, 'value': { 'kid': self.client_keys[KEY_USAGE_ENC].key_id, 'claims': claims } }
def create_authz_token(scopes=None): if scopes is None: scopes = [] if type(scopes) not in (list, tuple, set): scopes = [scopes] load_jwks(settings.JWKS_TEST_KEY) key = next(iter(_keyset['keys'])) now = int(time.time()) header = {'alg': 'ES256', 'kid': key.key_id} claims = { 'iat': now, 'exp': now + 3600, 'scopes': scopes, 'sub': '*****@*****.**', } token = JWT(header=header, claims=claims) token.make_signed_token(key) return token.serialize()
def _create_auth_token(self, secret: str, expiration_time: float) -> JWT: """ Create an admin auth token from the specified secret. By default, the token will be valid for 1 hour (3600 seconds). :param secret: :param valid_for: :return: """ token = JWT(header={'alg': 'HS256'}, claims={ 'sub': 'plastron', 'iss': 'plastron', 'exp': expiration_time, 'role': 'fedoraAdmin' }) key = JWK(kty='oct', k=secret) token.make_signed_token(key) return token
def _get_app_token(self): expired = self._is_token_expired(self._current_app_token_expiry) if expired: now = self._get_now_timestamp() expiry = now + (10 * 60) self._current_app_token_expiry = expiry token = JWT( header={'alg': 'RS256'}, claims={ 'iat': now, 'exp': expiry, 'iss': self._identifier, }, algs=['RS256'], ) token.make_signed_token(JWK.from_pem(self._private_key)) self._current_app_token = token.serialize() return self._current_app_token
def authenticate(client_id, code): payload = { "client_id": client_id, "client_secret": client_secret, "code": code } oauth_response = post("https://github.com/login/oauth/access_token", params=payload) oauth_json = urllib.parse.parse_qs(oauth_response.text) github_token = oauth_json["access_token"][0] user_response = get( "https://api.github.com/user", headers={"Authorization": "token " + github_token}, ) user = user_response.json() now = int(time.time()) token = JWT( header={ "typ": "JWT", "alg": "RS512" }, claims={ "user_id": user["id"], "username": user["login"], "email": user["email"], "github_token": github_token, }, default_claims={ "jti": True, "iss": issuer, "aud": issuer, "nbf": now, "iat": now, "exp": now + token_expiration_time, }, ) token.make_signed_token(key) return {"github_token": github_token, "repoadopt_token": token.serialize()}
def client_assertion(self, audience: str) -> str: iat = int(datetime.now().timestamp()) exp = iat + self.lifetime jti = str(self.jti_gen()) jwk = JWK(kty="oct", k=b64u_encode(self.client_secret)) jwt = JWT( header={"alg": self.alg}, claims={ "iss": self.client_id, "sub": self.client_id, "aud": audience, "iat": iat, "exp": exp, "jti": jti, }, ) jwt.make_signed_token(jwk) assertion: str = jwt.serialize() return assertion