Example #1
0
def _load(jwt):
    if isinstance(jwt, six.text_type):
        jwt = jwt.encode('utf-8')
    try:
        signing_input, crypto_segment = jwt.rsplit(b'.', 1)
        header_segment, claims_segment = signing_input.split(b'.', 1)
        header_data = base64url_decode(header_segment)
    except ValueError:
        raise JWSError('Not enough segments')
    except (TypeError, binascii.Error):
        raise JWSError('Invalid header padding')

    try:
        header = json.loads(header_data.decode('utf-8'))
    except ValueError as e:
        raise JWSError('Invalid header string: %s' % e)

    if not isinstance(header, Mapping):
        raise JWSError('Invalid header string: must be a json object')

    try:
        payload = base64url_decode(claims_segment)
    except (TypeError, binascii.Error):
        raise JWSError('Invalid payload padding')

    try:
        signature = base64url_decode(crypto_segment)
    except (TypeError, binascii.Error):
        raise JWSError('Invalid crypto padding')

    return (header, payload, signing_input, signature)
Example #2
0
    def _get_token(self):
        # Fetch key from server
        http_protocol = "http" if DMC_INSECURE else "https"
        self._logger.info(
            "attempting to authenticate on %s://%s" % (http_protocol, DMC_URI)
        )
        key = requests.get('{}://{}/drone/keys.json'.format(http_protocol, DMC_URI))
        if key.status_code >= 299:
            self._logger.error("could not fetch keys, server error")
            raise AuthException('could not access keys: {}'.format(key.status_code))
        key = key.json()

        # Authenticate
        anip_uri = DMC_ANIP_URI or "{}/drone/auth".format(DMC_URI)
        self._logger.info("fetching token from %s" % anip_uri)
        ret = requests.post("{}://{}".format(http_protocol, anip_uri),
                            json={
                                'id': self.drone_id,
                                'password': self.password
                            })
        if ret.status_code >= 500:
            raise AuthException('could not fetch token, server error')
        elif ret.status_code > 299:
            raise AuthException('unauthorized: {}'.format(ret))

        # Verify recieved token with key from server
        token = ret.json()['token']
        rsa_key = jwk.construct(key)
        message, encoded_sig = token.rsplit('.', 1)
        decoded_sig = base64url_decode(str(encoded_sig))
        if not rsa_key.verify(message, decoded_sig):
            raise AuthException('invalid token')
        payload = message.split('.')[1]
        auth = json.loads(base64url_decode(str(payload)))
        return token, auth
Example #3
0
def _load(jwt):
    if isinstance(jwt, six.text_type):
        jwt = jwt.encode('utf-8')
    try:
        signing_input, crypto_segment = jwt.rsplit(b'.', 1)
        header_segment, claims_segment = signing_input.split(b'.', 1)
        header_data = base64url_decode(header_segment)
    except ValueError:
        raise JWSError('Not enough segments')
    except (TypeError, binascii.Error):
        raise JWSError('Invalid header padding')

    try:
        header = json.loads(header_data.decode('utf-8'))
    except ValueError as e:
        raise JWSError('Invalid header string: %s' % e)

    if not isinstance(header, Mapping):
        raise JWSError('Invalid header string: must be a json object')

    try:
        payload = base64url_decode(claims_segment)
    except (TypeError, binascii.Error):
        raise JWSError('Invalid payload padding')

    try:
        signature = base64url_decode(crypto_segment)
    except (TypeError, binascii.Error):
        raise JWSError('Invalid crypto padding')

    return (header, payload, signing_input, signature)
Example #4
0
 def test_zip_header_not_present_when_none(self):
     enc = ALGORITHMS.A256CBC_HS512
     alg = ALGORITHMS.RSA_OAEP_256
     encrypted = jwe.encrypt("Text", PUBLIC_KEY_PEM, enc, alg,
                             zip=ZIPS.NONE)
     header = json.loads(six.ensure_str(base64url_decode(encrypted.split(b".")[0])))
     assert "zip" not in header
Example #5
0
 def test_cty_header_present_when_provided(self):
     enc = ALGORITHMS.A256CBC_HS512
     alg = ALGORITHMS.RSA_OAEP_256
     encrypted = jwe.encrypt("Text", PUBLIC_KEY_PEM, enc, alg,
                             cty="expected")
     header = json.loads(six.ensure_str(base64url_decode(encrypted.split(b".")[0])))
     assert header["cty"] == "expected"
def lambda_handler(event, context):
    token = event['token']
    # get the kid from the headers prior to verification
    headers = jwt.get_unverified_headers(token)
    kid = headers['kid']
    # search for the kid in the downloaded public keys
    key_index = -1
    for i in range(len(keys)):
        if kid == keys[i]['kid']:
            key_index = i
            break
    if key_index == -1:
        print('Public key not found in jwks.json')
        return False
    # construct the public key
    public_key = jwk.construct(keys[key_index])
    # get the last two sections of the token,
    # message and signature (encoded in base64)
    message, encoded_signature = str(token).rsplit('.', 1)
    # decode the signature
    decoded_signature = base64url_decode(encoded_signature)
    # verify the signature
    if public_key.verify(message, decoded_signature):
        print('Signature successfully verified')
        # since we passed the verification, now we can safely
        # get the unverified claims
        claims = jwt.get_unverified_claims(token)
        # do some stuff with our claims
        print(claims)
        return claims
    else:
        print('Signature verification failed')
        return False
Example #7
0
def token_decoder(token):
    set_cognito_data_global()
    headers = jwt.get_unverified_headers(token)
    kid = headers['kid']

    result = {}
    for item in POOL_KEYS:
        result[item['kid']] = item

    public_key = jwk.construct(result.get(kid))
    message, encoded_signature = str(token).rsplit('.', 1)
    decoded_signature = base64url_decode(encoded_signature.encode('utf-8'))

    if not public_key.verify(message.encode("utf8"), decoded_signature):
        app.logger.error('Signature verification failed')
        raise Exception

    app.logger.debug('Signature successfully verified')
    claims = jwt.get_unverified_claims(token)

    if time.time() > claims['exp']:
        app.logger.error('Token is expired')
        raise Exception
    app.logger.debug(claims)
    return claims
Example #8
0
def validate_token(access_token, issuer, audience, client_ids):
    # Client ID's list
    cid_list = []

    if not isinstance(client_ids, list):
        cid_list = client_ids.split(',')
    else:
        cid_list = client_ids

    check_presence_of(access_token, issuer, audience, cid_list)

    # Decoding Header & Payload from token
    header = jwt.get_unverified_header(access_token)
    payload = jwt.get_unverified_claims(access_token)

    # Verifying Claims
    verify_claims(payload, issuer, audience, cid_list)

    # Verifying Signature
    jwks_key = fetch_jwk_for(header, payload)
    key = jwk.construct(jwks_key)
    message, encoded_sig = access_token.rsplit('.', 1)
    decoded_sig = base64url_decode(encoded_sig.encode('utf-8'))

    valid = key.verify(message.encode(), decoded_sig)

    # If the token is valid, it returns the payload
    if valid == True:
        return payload
    else:
        raise Exception('Invalid Token')
Example #9
0
    def get_username_from_token(self, token):
        if self.keys is None:
            (self.keys, self.keys_iss) = self.__get_userpool_keys()

        try:
            headers = jwt.get_unverified_header(token)
        except:
            return None
        if not headers.get('kid'):
            return None
        kid = headers['kid']

        key_index = -1
        for i in range(len(self.keys)):
            if kid == self.keys[i]['kid']:
                key_index = i
                break
        if key_index == -1:
            return None

        public_key = jwk.construct(self.keys[key_index])
        message, encoded_signature = str(token).rsplit('.', 1)
        decoded_signature = base64url_decode(encoded_signature.encode('utf-8'))
        if not public_key.verify(message.encode("utf8"), decoded_signature):
            return None

        claims = jwt.get_unverified_claims(token)
        return claims["username"]
Example #10
0
    def verify_signature(self, token, pkey_data):
        """
      #Verifica si no a modificado Payload del token
      #Mediante la signature
    Args:
        token (string): jwt
        pkey_data ([type]): [description]

    Raises:
        VerifyTokenException: [description]
        VerifyTokenException: [description]
    """
        try:
            # Key data
            public_key = jwk.construct(pkey_data)
        except JOSEError:
            raise CustomException(status_code=401,
                                  type='signature',
                                  detail='Token inválido')

        #Obtiene Signature
        message, encoded_signature = str(token).rsplit(".", 1)

        # Decodifica Signature
        decoded_signature = base64url_decode(encoded_signature.encode("utf-8"))
        # Verifica Signature
        if not public_key.verify(message.encode("utf8"), decoded_signature):
            raise CustomException(
                status_code=401,
                type='signature',
                detail='Token a sido Modificado, Signature inválido!')
Example #11
0
    def test_deterministic_headers(self):
        from collections import OrderedDict
        from jose.utils import base64url_decode

        claims = {"a": "b"}
        key = "secret"

        headers1 = OrderedDict((
            ('kid', 'my-key-id'),
            ('another_key', 'another_value'),
        ))
        encoded1 = jwt.encode(claims, key, algorithm='HS256', headers=headers1)
        encoded_headers1 = encoded1.split('.', 1)[0]

        headers2 = OrderedDict((
            ('another_key', 'another_value'),
            ('kid', 'my-key-id'),
        ))
        encoded2 = jwt.encode(claims, key, algorithm='HS256', headers=headers2)
        encoded_headers2 = encoded2.split('.', 1)[0]

        assert encoded_headers1 == encoded_headers2

        # manually decode header to compare it to known good
        decoded_headers1 = base64url_decode(encoded_headers1.encode('utf-8'))
        assert decoded_headers1 == b"""{"alg":"HS256","another_key":"another_value","kid":"my-key-id","typ":"JWT"}"""
Example #12
0
def lambda_handler(event, context):
    print(event)

    token = event['request']['headers']['v-cognito-user-jwt']

    headers = jwt.get_unverified_headers(token)
    kid = headers['kid']

    key_index = -1
    for i in range(len(KEYS)):
        if kid == KEYS[i]['kid']:
            key_index = i
            break

    if key_index == -1:
        print('Public key not found in jwks.json')
        return 'jwks failed validation - return Public key'

    public_key = jwk.construct(KEYS[key_index])
    message, encoded_signature = str(token).rsplit('.', 1)

    decoded_signature = base64url_decode(encoded_signature.encode('utf-8'))

    if not public_key.verify(message.encode('utf8'), decoded_signature):
        print('Signature verification failed')
        return 'jwks failed validation - return Signature'

    claims = jwt.get_unverified_claims(token)
    print(claims)
    print(claims['email'])
    claims['cognito_username'] = claims['cognito:username']
    claims['cognito_groups'] = claims['cognito:groups']

    return claims
def get_claims(logger: logging.Logger, token: str) -> Dict[str, Union[str, int]]:
    # client_id = os.environ["COGNITO_APP_CLIENT_ID"]
    # get the kid from the headers prior to verification
    headers: Dict[str, str] = cast(Dict[str, str], jwt.get_unverified_headers(token=token))
    kid: str = headers["kid"]
    # search for the kid in the downloaded public keys
    for key in _get_keys(logger):
        if kid == key["kid"]:
            # construct the public key
            public_key = jwk.construct(key_data=key)
            break
    else:
        raise ValueError("Public key not found in JWK.")
    # get the last two sections of the token,
    # message and signature (encoded in base64)
    message, encoded_signature = token.rsplit(".", 1)
    # decode the signature
    decoded_signature: bytes = base64url_decode(encoded_signature.encode("utf-8"))
    # verify the signature
    if public_key.verify(msg=message.encode("utf8"), sig=decoded_signature) is False:
        raise RuntimeError("Signature verification failed.")
    logger.debug("Signature validaded.")
    # since we passed the verification, we can now safely use the unverified claims
    claims = jwt.get_unverified_claims(token)
    # additionally we can verify the token expiration
    if time.time() > int(claims["exp"]):
        raise ValueError("Token expired.")
    logger.debug("Token not expired.")
    logger.debug("claims: %s", claims)

    return cast(Dict[str, Union[str, int]], claims)
Example #14
0
def get_claims(token: str) -> Dict[str, Union[str, int]]:
    # get the kid from the headers prior to verification
    headers: Dict[str, str] = cast(Dict[str, str], jwt.get_unverified_headers(token=token))
    kid: str = headers["kid"]
    # search for the kid in the downloaded public keys
    for key in _get_keys():
        if kid == key["kid"]:
            # construct the public key
            public_key = jwk.construct(key_data=key)
            break
    else:
        raise ValueError("Public key not found in JWK.")
    # get the last two sections of the token,
    # message and signature (encoded in base64)
    message, encoded_signature = token.rsplit(".", 1)
    # decode the signature
    decoded_signature: bytes = base64url_decode(encoded_signature.encode("utf-8"))
    # verify the signature
    if public_key.verify(msg=message.encode("utf8"), sig=decoded_signature) is False:
        raise RuntimeError("Signature verification failed.")
    print("Signature validaded.")
    # since we passed the verification, we can now safely use the unverified claims
    claims: Dict[str, Union[str, int]] = cast(Dict[str, Union[str, int]], jwt.get_unverified_claims(token))
    # additionally we can verify the token expiration
    if time.time() > int(claims["exp"]):
        raise ValueError("Token expired.")
    print("Token not expired.")
    # and the Audience (use claims['client_id'] if verifying an access token)
    if claims["aud"] != COGNITO_USER_POOL_CLIENT_ID:
        raise ValueError("Token was not issued for this audience.")
    # now we can use the claims
    return claims
Example #15
0
 def test_zip_header_present_when_provided(self):
     enc = ALGORITHMS.A256CBC_HS512
     alg = ALGORITHMS.RSA_OAEP_256
     encrypted = jwe.encrypt("Text", PUBLIC_KEY_PEM, enc, alg, zip=ZIPS.DEF)
     header = json.loads(
         six.ensure_str(base64url_decode(encrypted.split(".")[0])))
     assert header["zip"] == ZIPS.DEF
    def run(self):
        self.identifier = self.signed_se['header']['uniqueId']
        print('\tUnique ID: {}'.format(self.identifier.upper()))

        # Decode the protected header
        protected = json.loads(
            base64url_decode(self.signed_se['protected'].encode('ascii')))
        if protected['kid'] != self.verification_cert_kid_b64:
            raise ValueError('kid does not match certificate value')
        if protected['x5t#S256'] != self.verification_cert_x5t_s256_b64:
            raise ValueError('x5t#S256 does not match certificate value')
        # Convert JWS to compact form as required by python-jose
        jws_compact = '.'.join([
            self.signed_se['protected'], self.signed_se['payload'],
            self.signed_se['signature']
        ])
        # Verify and decode the payload. If verification fails an exception will
        # be raised.
        se = json.loads(
            jose.jws.verify(token=jws_compact,
                            key=self.verification_public_key_pem,
                            algorithms=verification_algorithms))
        try:
            public_keys = se['publicKeySet']['keys']
        except KeyError:
            public_keys = []
        for jwk in public_keys:
            cert_chain = ''
            for cert_b64 in jwk.get('x5c', []):
                cert = x509.load_der_x509_certificate(
                    data=b64decode(cert_b64), backend=default_backend())
                self.certificate_chain = self.certificate_chain + cert.public_bytes(
                    encoding=serialization.Encoding.PEM).decode('ascii')
 def find_valid_key(self, id_token):
     for key in self.get_jwks_keys():
         rsakey = jwk.construct(key)
         message, encoded_sig = id_token.rsplit('.', 1)
         decoded_sig = base64url_decode(encoded_sig.encode('utf-8'))
         if rsakey.verify(message.encode('utf-8'), decoded_sig):
             return key
Example #18
0
def verified_claims(token: str,
                    app_client_id: str = os.environ.get('COGNITO_CLIENT_ID'),
                    public_keys: dict = None) -> bool:
    """

    verified token signature, expiry and app_id then returns claims
    """
    headers = jwt.get_unverified_headers(token)
    kid = headers['kid']

    public_keys = public_keys or get_cognito_public_keys()
    public_key = jwk.construct(public_keys[kid])

    message, encoded_signature = str(token).rsplit('.', 1)
    decoded_signature = base64url_decode(encoded_signature.encode('utf-8'))

    if not public_key.verify(message.encode("utf8"), decoded_signature):
        raise RuntimeError(f'Signature verification failed')

    claims = jwt.get_unverified_claims(token)
    if time.time() > claims['exp']:
        expiry = datetime.fromtimestamp(claims['exp'])
        raise RuntimeError(
            f"Token expired at {expiry}, it is now {datetime.now()}")

    if app_client_id and claims['client_id'] != app_client_id:
        raise RuntimeError(
            f"Token audience {claims['aud']} was not issued for this audience {app_client_id}"
        )

    return claims
Example #19
0
 def test_alg_enc_headers(self):
     enc = ALGORITHMS.A256CBC_HS512
     alg = ALGORITHMS.RSA_OAEP_256
     encrypted = jwe.encrypt("Text", PUBLIC_KEY_PEM, enc, alg)
     header = json.loads(base64url_decode(encrypted.split(b".")[0]))
     assert header["enc"] == enc
     assert header["alg"] == alg
    def __validateSignatureJWS(self, token):
        userPoolId = settings.AWS_CONFIG['USER_POOL_ID']
        region = settings.AWS_CONFIG['REGION']

        keysUrl = 'https://cognito-idp.{}.amazonaws.com/{}/.well-known/jwks.json'.format(
            region, userPoolId)
        with urllib.request.urlopen(keysUrl) as f:
            response = f.read()
        keys = json.loads(response.decode('utf-8'))['keys']

        headers = jwt.get_unverified_headers(token)
        kid = headers['kid']
        keyIndex = -1
        for i in range(len(keys)):
            if kid == keys[i]['kid']:
                keyIndex = i
                break
        if keyIndex == -1:
            return False, 'Public key not found in jwks.json'

        publicKey = jwk.construct(keys[keyIndex])
        payload, signature = str(token).rsplit('.', 1)
        decodedSignature = base64url_decode(signature.encode('utf-8'))
        if not publicKey.verify(payload.encode("utf8"), decodedSignature):
            return False, 'Signature verification failed'

        return True, None
Example #21
0
def get_and_verify_claims(token):
    # get the kid from the headers prior to verification
    headers = jwt.get_unverified_headers(token)
    kid = headers['kid']
    # search for the kid in the downloaded public keys
    key_index = -1
    for i in range(len(keys)):
        if kid == keys[i]['kid']:
            key_index = i
            break
    if key_index == -1:
        raise Exception("Public key not found in jwks.json")
    # construct the public key
    public_key = jwk.construct(keys[key_index])
    # get the last two sections of the token,
    # message and signature (encoded in base64)
    message, encoded_signature = str(token).rsplit('.', 1)
    # decode the signature
    decoded_signature = base64url_decode(encoded_signature.encode('utf-8'))
    # verify the signature
    if not public_key.verify(message.encode("utf8"), decoded_signature):
        raise Exception('Signature verification failed')
    # since we passed the verification, we can now safely
    # use the unverified claims
    claims = jwt.get_unverified_claims(token)
    # additionally we can verify the token expiration
    if time.time() > claims['exp']:
        raise Exception('Token is expired')
    # and the Audience  (use claims['client_id'] if verifying an access token)
    if claims['aud'] != app_client_id:
        raise Exception('Token was not issued for this audience')
    # now we can use the claims
    return claims
Example #22
0
    def test_deterministic_headers(self):
        from collections import OrderedDict
        from jose.utils import base64url_decode

        claims = {"a": "b"}
        key = "secret"

        headers1 = OrderedDict((
            ('kid', 'my-key-id'),
            ('another_key', 'another_value'),
        ))
        encoded1 = jwt.encode(claims, key, algorithm='HS256', headers=headers1)
        encoded_headers1 = encoded1.split('.', 1)[0]

        headers2 = OrderedDict((
            ('another_key', 'another_value'),
            ('kid', 'my-key-id'),
        ))
        encoded2 = jwt.encode(claims, key, algorithm='HS256', headers=headers2)
        encoded_headers2 = encoded2.split('.', 1)[0]

        assert encoded_headers1 == encoded_headers2

        # manually decode header to compare it to known good
        decoded_headers1 = base64url_decode(encoded_headers1.encode('utf-8'))
        assert decoded_headers1 == b"""{"alg":"HS256","another_key":"another_value","kid":"my-key-id","typ":"JWT"}"""
Example #23
0
def token_decoder(token):
    """
    The ID token expires one hour after the user authenticates.
    You should not process the ID token in your client or web API after it has expired.
    https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html
    :param token:
    :return:
    """
    set_cognito_data_global()
    token = remove_barer(token)

    headers = jwt.get_unverified_headers(token)
    kid = headers['kid']

    result = {}
    for item in POOL_KEYS:
        result[item['kid']] = item

    public_key = jwk.construct(result.get(kid))

    message, encoded_signature = str(token).rsplit('.', 1)
    decoded_signature = base64url_decode(encoded_signature.encode('utf-8'))

    if not public_key.verify(message.encode("utf8"), decoded_signature):
        raise UnauthorizedError('Invalid Token')

    claims = jwt.get_unverified_claims(token)

    if time.time() > claims['exp']:
        raise UnauthorizedError('Token in expired!')
    return claims
Example #24
0
 def test_kid_header_not_present_when_not_provided(self):
     enc = ALGORITHMS.A256CBC_HS512
     alg = ALGORITHMS.RSA_OAEP_256
     encrypted = jwe.encrypt("Text", PUBLIC_KEY_PEM, enc, alg)
     header = json.loads(
         six.ensure_str(base64url_decode(encrypted.split(".")[0])))
     assert "kid" not in header
    def extract_public_data_pem(self, se_object):
        '''
        Function extract the publickey JWK object from secure element and return it in pem format
        Inputs:
              se_object           contains secure element object
        Outputs:
              slots               contains public keys in pem format
        '''
        try:
            public_keys = se_object['publicKeySet']['keys']
        except KeyError:
            public_keys = []

        slots = []
        for jwk in public_keys:
            if jwk['kty'] not in ['EC', 'RSA', 'oct']:
                print('Unsupported {}'.format(json.dumps({'kty': jwk['kty']})))
                continue
            if jwk['crv'] not in ['P-256', 'P-384', 'P-521']:
                print('Unsupported {}'.format(json.dumps({'crv': jwk['crv']})))
                continue

            slot = {}
            slot.update({'id': jwk['kid']})
            public_key = ec.EllipticCurvePublicNumbers(
                curve=ec.SECP256R1(),
                x=int.from_bytes(base64url_decode(
                    jwk['x'].encode('utf8')), byteorder='big', signed=False),
                y=int.from_bytes(base64url_decode(
                    jwk['y'].encode('utf8')), byteorder='big', signed=False)
            ).public_key(default_backend())
            slot.update({'pub_key': public_key.public_bytes(
                encoding=serialization.Encoding.PEM,
                format=serialization.PublicFormat.SubjectPublicKeyInfo).decode('ascii')})

            # Decode any available certificates
            slot_certs = []
            for cert_b64 in jwk.get('x5c', []):
                cert = x509.load_der_x509_certificate(
                    data=b64decode(cert_b64), backend=default_backend())
                slot_certs.append(
                    cert.public_bytes(
                        encoding=serialization.Encoding.PEM).decode('ascii'))
            slot.update({'certs': slot_certs})
            slots.append(slot)

        return slots
Example #26
0
async def _verify_signature(app, jws, payload):
    jws_header_b64, _, signature_b64 = jws.split('.')
    signature = base64url_decode(signature_b64.encode())
    header_str = base64url_decode(jws_header_b64.encode())
    header = json.loads(header_str)

    if header.get('jku') != app.config.expected_jwks_uri:
        return False
    response = await app.aiohttp_session.get(app.config.expected_jwks_uri)
    jwks = await response.json()
    # Get the first key with ID matching the header's
    raw_key = next(k for k in jwks['keys'] if k.get('kid') == header['kid'])
    key = jwk.construct(raw_key)
    payload_b64 = base64url_encode(payload).decode()
    secured_input = f'{jws_header_b64}.{payload_b64}'

    return key.verify(secured_input.encode(), signature)
Example #27
0
 def find_valid_key(self, id_token):
     for key in self.get_jwks_keys():
         rsakey = jwk.construct(key)
         message, encoded_sig = id_token.rsplit('.', 1)
         decoded_sig = base64url_decode(encoded_sig.encode('utf-8'))
         if rsakey.verify(message.encode('utf-8'), decoded_sig):
             return key
     return False
Example #28
0
def get_current_user(db: Session = Depends(get_db),
                     token: str = Security(reusable_oauth2)):

    # try:
    #     payload = jwt.decode(token, config.SECRET_KEY, algorithms=[ALGORITHM])
    #     token_data = TokenPayload(**payload)
    # except PyJWTError:
    #     raise HTTPException(
    #         status_code=HTTP_403_FORBIDDEN, detail="Could not validate credentials"
    #     )
    # user = crud.user.get(db, user_id=token_data.user_id)
    # if not user:
    #     raise HTTPException(status_code=404, detail="User not found")
    # return user

    # get the kid from the headers prior to verification
    headers = jwt.get_unverified_headers(token)
    kid = headers['kid']
    # search for the kid in the downloaded public keys
    key_index = -1
    for i in range(len(keys)):
        if kid == keys[i]['kid']:
            key_index = i
            break
    if key_index == -1:
        logger.info('Public key not found in jwks.json')
        return False
    # construct the public key
    public_key = jwk.construct(keys[key_index])
    # get the last two sections of the token,
    # message and signature (encoded in base64)
    message, encoded_signature = str(token).rsplit('.', 1)
    # decode the signature
    decoded_signature = base64url_decode(encoded_signature.encode('utf-8'))
    # verify the signature
    if not public_key.verify(message.encode("utf8"), decoded_signature):
        logger.info('Signature verification failed')
        return False
    logger.info('Signature successfully verified')
    # since we passed the verification, we can now safely
    # use the unverified claims
    claims = jwt.get_unverified_claims(token)
    # additionally we can verify the token expiration
    if time.time() > claims['exp']:
        logger.info('Token is expired')
        raise HTTPException(status_code=404, detail="Sessions has expired.")
    # and the Audience  (use claims['client_id'] if verifying an access token)
    if claims['client_id'] != app_client_id:
        logger.info('Token was not issued for this audience')
        raise HTTPException(status_code=404,
                            detail="Unauthorized access. Access denied")
    # now we can use the claims
    # print(claims)

    user = crud.user.get(db, cognito_user_id=claims["sub"])
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    return user
def decode_cognito_token(token, cognito_clinet_id, aws_keys):
    result = {}
    try:
        headers = jwt.get_unverified_headers(token)
    except Exception as e:
        result = {"error": str(e)}
        logging.error(result)
        return result
    else:
        logging.info(json.dumps(headers))
        id_kid = headers['kid']
        logging.info(f'kid:{id_kid} found in idtoken')
    # search for the kid in the downloaded public keys
    key_index = -1
    for count in range(len(aws_keys['keys'])):
        if aws_keys['keys'][count]['kid'] == id_kid:
            logging.info(f"matched idtoken kid with AWS kid index:{count}")
            key_index = count
    if key_index == -1:
        logging.error('Public key not found in jwks.json')
        result = {"error": "Public key not found in jwks.json"}
        return result
    # construct the public key
    public_key = jwk.construct(aws_keys['keys'][key_index])
    # get the last two sections of the token,
    # message and signature (encoded in base64)
    message, encoded_signature = str(token).rsplit('.', 1)
    # decode the signature
    decoded_signature = base64url_decode(encoded_signature.encode('utf-8'))
    # verify the signature
    if not public_key.verify(message.encode("utf8"), decoded_signature):
        logging.error('Signature verification failed')
        result = {"error": "Signature verification failed"}
        return result
    logging.info('Signature successfully verified')
    # since we passed the verification, we can now safely
    # use the unverified claims
    claims = jwt.get_unverified_claims(token)
    # additionally we can verify the token expiration
    if time.time() > claims['exp']:
        logging.error('Token has expired')
        result = {"error": "Token has expired"}
        return result
    # and the Audience  (use claims['client_id'] if verifying an access token)
    if claims['token_use'] == 'id':
        if claims['aud'] != cognito_clinet_id:
            logging.error('Token was not issued for this audience')
            result = {"error": "Token was not issued for this audience"}
            return result
    if claims['token_use'] == 'access':
        if claims['client_id'] != cognito_clinet_id:
            logging.error('Token was not issued for this audience')
            result = {"error": "Token was not issued for this audience"}
            return result

    result['data'] = claims
    return result
    ''''''
Example #30
0
    def verify_token(self, token, username):
        if self.keys is None:
            (self.keys, self.keys_iss) = self.__get_userpool_keys()

        # get the kid from the headers prior to verification
        try:
            headers = jwt.get_unverified_header(token)
        except:
            return 6
        if not headers.get('kid'):
            return 7
        kid = headers['kid']

        # search for the kid in the downloaded public keys
        key_index = -1
        for i in range(len(self.keys)):
            if kid == self.keys[i]['kid']:
                key_index = i
                break
        if key_index == -1:
            print('Public key not found in jwks.json')
            return 8

        # construct the public key
        public_key = jwk.construct(self.keys[key_index])

        # get the last two sections of the token,
        # message and signature (encoded in base64)
        message, encoded_signature = str(token).rsplit('.', 1)

        # decode the signature
        decoded_signature = base64url_decode(encoded_signature.encode('utf-8'))

        # verify the signature
        if not public_key.verify(message.encode("utf8"), decoded_signature):
            print('Signature verification failed')
            return 9

        # since we passed the verification, we can now safely
        # use the unverified claims
        claims = jwt.get_unverified_claims(token)
        if claims["token_use"] != "access":
            print('Token is not an access token')
            return 1
        curr_time = int(time.time())
        if curr_time > claims["exp"] or curr_time < claims["iat"]:
            #print('Token is expired {} [iat {}, exp {}]'.format(curr_time, claims["iat"], claims["exp"]))
            return 2
        if claims["client_id"] != config.CONFIG_CLIENT_ID:
            print('Token was not issued for this client_id')
            return 3
        if claims["username"] != username:
            print('Token was not issued for this username')
            return 4
        if claims['iss'] != self.keys_iss:
            print('Token was not issued for this pool_id')
            return 5
        return 0
Example #31
0
 def _process_cert(self, key):
     pemLines = key.replace(b' ', b'').split()
     certDer = base64url_decode(b''.join(pemLines[1:-1]))
     certSeq = DerSequence()
     certSeq.decode(certDer)
     tbsSeq = DerSequence()
     tbsSeq.decode(certSeq[0])
     self.prepared_key = RSA.importKey(tbsSeq[6])
     return
Example #32
0
def verify_jwt(region, user_pool_id, app_client_id, token_type, token):
    this_region = region
    this_user_pool_id = user_pool_id
    this_token_type = token_type
    this_token = token
    this_app_client_id = app_client_id

    keys_url = "https://cognito-idp.{}.amazonaws.com/{}/.well-known/jwks.json".format(
        this_region, this_user_pool_id
    )

    with urllib.request.urlopen(keys_url) as f:
        response = f.read()
    keys = json.loads(response.decode("utf-8"))["keys"]
    headers = jwt.get_unverified_headers(this_token)
    kid = headers["kid"]
    # search for the kid in the downloaded public keys
    key_index = -1
    for i in range(len(keys)):
        if kid == keys[i]["kid"]:
            key_index = i
            break
    if key_index == -1:
        log.error("Public key not found in jwks.json")
        return False
    # construct the public key
    public_key = jwk.construct(keys[key_index])
    # get the last two sections of the token,
    # message and signature (encoded in base64)
    message, encoded_signature = str(this_token).rsplit(".", 1)
    # decode the signature
    decoded_signature = base64url_decode(encoded_signature.encode("utf-8"))
    # verify the signature
    if not public_key.verify(message.encode("utf8"), decoded_signature):
        log.error("Signature verification failed")
        return False
    log.info("Identity token signature successfully verified")
    # since we passed the verification, we can now safely
    # use the unverified claims
    claims = jwt.get_unverified_claims(this_token)
    # additionally we can verify the token expiration
    if time.time() > claims["exp"]:
        log.error("Token is expired")
        return False
    # and the Audience  (use claims['client_id'] if verifying an access token)
    if this_token_type == "access_token":
        if claims["client_id"] != this_app_client_id:
            log.error("Token was not issued for this audience")
            return False
    elif this_token_type == "id_token":
        if claims["aud"] != this_app_client_id:
            log.error("Token was not issued for this audience")
            return False
    else:
        return False
    # now we can use the claims
    return claims
Example #33
0
 def _verify(self, token):
     headers = jwt.get_unverified_headers(token)
     kid = headers['kid']
     key = self._get_key(kid)
     public_key = jwk.construct(key)
     message, encoded_signature = str(token).rsplit('.', 1)
     decoded_signature = base64url_decode(encoded_signature.encode('utf-8'))
     if not public_key.verify(message.encode("utf8"), decoded_signature):
         raise InvalidToken('Signature verification failed')
 def _process_cert(self, key):
     pemLines = key.replace(b' ', b'').split()
     certDer = base64url_decode(b''.join(pemLines[1:-1]))
     certSeq = DerSequence()
     certSeq.decode(certDer)
     tbsSeq = DerSequence()
     tbsSeq.decode(certSeq[0])
     self.prepared_key = RSA.importKey(tbsSeq[6])
     return
Example #35
0
    def _process_jwk(self, jwk_dict):
        if not jwk_dict.get('kty') == 'oct':
            raise JWKError("Incorrect key type.  Expected: 'oct', Recieved: %s" % jwk_dict.get('kty'))

        k = jwk_dict.get('k')
        k = k.encode('utf-8')
        k = bytes(k)
        k = base64url_decode(k)

        return k