示例#1
0
 def test_non_default_headers(self, claims, key, headers):
     encoded = jwt.encode(claims, key, headers=headers)
     decoded = jwt.decode(encoded, key)
     assert claims == decoded
     all_headers = jwt.get_unverified_headers(encoded)
     for k, v in headers.items():
         assert all_headers[k] == v
示例#2
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
示例#3
0
    def verify_oidc(cls, handler):
        global user_cache
        oidc_id = handler.request.headers.get('x-amzn-oidc-identity')
        oidc_jwt = handler.request.headers.get('x-amzn-oidc-data')
        oidc_access = handler.request.headers.get('x-amzn-oidc-accesstoken')

        handler.log.debug("IDs: {}, {}, {}".format(oidc_id, oidc_access, oidc_jwt))
                     
        if oidc_id != user_cache.get('container_uid'):
            return False
            
        if not oidc_id or not oidc_jwt:
            return False
        if oidc_id != user_cache.get('user_id'):
            return False
        if oidc_jwt != user_cache.get('jwt'):
            return False
        try:
            header = jwt.get_unverified_headers(oidc_jwt)
        except JOSEError:
            return False
        kid = header.get('kid')
        if kid != user_cache.get('kid'):
            return False

        # TODO: TIMESTAMP CHECK
        return True
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)
示例#5
0
 def test_non_default_headers(self, claims, key, headers):
     encoded = jwt.encode(claims, key, headers=headers)
     decoded = jwt.decode(encoded, key)
     assert claims == decoded
     all_headers = jwt.get_unverified_headers(encoded)
     for k, v in headers.items():
         assert all_headers[k] == v
示例#6
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
示例#7
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
    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
示例#9
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
示例#10
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
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
示例#12
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
示例#13
0
def verify_decode_jwt(token):
    jsonurl = urlopen(f'https://{AUTH0_DOMAIN}/.well-known/jwks.json')
    jwks = json.loads(jsonurl.read())
    unverified_header = jwt.get_unverified_headers(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)
示例#14
0
    def _get_kid(token: str) -> str:
        headers = jwt.get_unverified_headers(token)
        kid = headers.get("kid", None)

        if kid is None:
            raise Exception("Missing kid in header")

        return kid
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
    ''''''
示例#16
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
示例#17
0
def search_for_key(token, keys):
    # 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
    for key in keys:
        if kid == key["kid"]:
            return key
    raise JWTError(f"Public key not found in provided keys")
示例#18
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 decode_cognito_token(token):
    result = {}
    '''
    from https://github.com/awslabs/aws-support-tools/blob/master/Cognito/decode-verify-jwt/decode-verify-jwt.py
    '''
    try:
        headers = jwt.get_unverified_headers(token)
    except Exception as e:
        result = {"error": str(e)}
        return result
    else:
        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:
        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(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_CLIENT_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_CLIENT_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
示例#20
0
def lambda_handler(event, context):
    token = event['queryStringParameters']['id_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 {
            "statusCode":500,
            "body": "Public key not found"
        }
    # 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):
        # print('Signature verification failed')
        return {
            "statusCode":500,
            "body": "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']:
        return {
            "statusCode":500,
            "body": "Token is expired."
        }
    # and the Audience  (use claims['client_id'] if verifying an access token)
    if claims['aud'] != app_client_id:
        print('Token was not issued for this audience')
        return False
    # now we can use the claims
    #TODO SEND BACK THE JWT
    #TODO send back user data here?
    return {
            'statusCode':302,
            'headers': {
                'location' : 'https://busy-bee.app'
            },
            'body': json.dumps(claims)
        }
示例#21
0
def sso_authorization(code):
    authorization = 'Basic ' + base64.b64encode(
        (config.Config.COGNITO_APP_ID + ':' +
         config.Config.COGNITO_APP_SECRET).encode()).decode()
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Authorization': authorization
    }

    data = {
        'grant_type': 'authorization_code',
        'client_id': config.Config.COGNITO_APP_ID,
        'code': code,
        'redirect_uri': config.Config.COGNITO_CALLBACK_URL
    }

    oauth_token = requests.post(config.Config.COGNITO_OAUTH_TOKEN_ENDPOINT,
                                data=data,
                                headers=headers).json()
    id_token = oauth_token['id_token']
    access_token = oauth_token['access_token']
    headers = jwt.get_unverified_headers(id_token)
    keys = requests.get(
        config.Config.COGNITO_JWS_KEYS_ENDPOINT).json().get('keys')
    key = list(filter(lambda k: k['kid'] == headers['kid'], keys)).pop()
    claims = jwt.decode(id_token,
                        key,
                        access_token=access_token,
                        algorithms=[key['alg']],
                        audience=config.Config.COGNITO_APP_ID)
    if claims:
        try:
            user = claims['email'].split('@')[0]
        except Exception as err:
            return {
                'success':
                False,
                'message':
                'Error reading SSO claims. ' + str(claims) + ' Err: ' +
                str(err)
            }

        # Simply check if user exist
        check_user = get(config.Config.FLASK_ENDPOINT + "/api/ldap/user",
                         headers={"X-SOCA-TOKEN": config.Config.API_ROOT_KEY},
                         params={"user": user},
                         verify=False)  # nosec
        if check_user.status_code == 200:
            session['user'] = user

            return {'success': True, 'message': ''}
        else:
            return {'success': False, 'message': 'user_not_found'}
    else:
        return {'success': False, 'message': 'SSO error. ' + str(claims)}
示例#22
0
def validate_token(config, token):
    region = 'us-east-1'
    user_record = {}
    keys_url = 'https://cognito-idp.{}.amazonaws.com/{}/.well-known/jwks.json'.format(
        region, config['cognito_pool'])
    response = urlopen(keys_url)
    keys = json.loads(response.read())['keys']

    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:
        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(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'

    # since we passed the verification, we can now safely
    # use the unverified claims
    claims = jwt.get_unverified_claims(token)

    log_error('Token claims = ' + json.dumps(claims))

    # additionally we can verify the token expiration
    if time.time() > claims['exp']:
        log_error('Token is expired')
        return 'False'

    if claims['aud'] != config['cognito_client_id']:
        log_error('Token claims not valid for this application')
        return 'False'

    user_record['username'] = claims['cognito:username']
    user_record['token'] = token

    return user_record
示例#23
0
文件: auth.py 项目: epiviz/epiviz-ws
def is_token_valid(token: str):
    # print("in is token valid")
    # print(token)
    global CERTS
    # get the kid from the headers prior to verification
    headers = jwt.get_unverified_headers(token)

    kid = headers['kid']
    # use that kid to get the public key from keycloak
    key_data = get_public_key_data(kid)

    # construct the public key
    public_key = jwk.construct(key_data)

    # 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 HTTPException(
            status_code=400,
            detail="Invalid token, {}".format("failed signature"),
            headers={"WWW-Authenticate": "Bearer"},
        )

    # since we passed the verification, we can now safely
    # use the unverified claims
    claims = jwt.get_unverified_claims(token)
    # print(claims)

    # additionally we can verify the token expiration
    if time.time() > claims['exp']:  # time() returns epoch (UTC)
        print('Token has expired')

    if claims.get("resource_access"):
        if "Epiviz" in claims.get("resource_access"):
            return User(username=claims.get("preferred_username"),
                        email=claims.get("email"),
                        full_name=claims.get("name"),
                        roles=claims.get("resource_access")["Epiviz"]["roles"])
        elif "Epiviz-backend" in claims.get("resource_access"):
            return User(
                username=claims.get("preferred_username"),
                email=claims.get("email"),
                full_name=claims.get("name"),
                roles=claims.get("resource_access")["Epiviz-backend"]["roles"])

    return User(username=claims.get("preferred_username"),
                email=claims.get("email"),
                full_name=claims.get("name"))
    def _verify_id_token(self):

        try:
            keys_url = 'https://cognito-idp.{}.amazonaws.com/{}/.well-known/jwks.json'.format(
                self.region, self.user_pool_id)
            response = urllib.urlopen(keys_url)
            keys = json.loads(response.read())['keys']

            # get the kid from the headers prior to verification
            headers = josejwt.get_unverified_headers(self.id_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(self.id_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 False
            print('Signature successfully verified')
            # since we passed the verification, we can now safely
            # use the unverified claims
            claims = josejwt.get_unverified_claims(self.id_token)
            # additionally we can verify the token expiration
            if time.time() > claims['exp']:
                print('Token is expired')
                return False
            # and the Audience  (use claims['client_id'] if verifying an access token)
            if claims['aud'] != self.client_id:
                print('Token was not issued for this audience')
                return False
            # now we can use the claims
            # print(claims)
            return True

        except Exception as e:
            print("Error verifying token: %s" % e.message)
            return False
示例#25
0
    def decode_verify_jwt_token(self, jwt_token):
        # copied from https://github.com/awslabs/aws-support-tools/blob/master/Cognito/decode-verify-jwt/decode-verify-jwt.py

        token = jwt_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(self.keys)):
            if kid == self.keys[i]['kid']:
                key_index = i
                break
        if key_index == -1:
            logging.warning('Public key not found in jwks.json')
            return False

        # 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):
            logging.warning('Signature verification failed')
            return False
        # print('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.warning('Token is expired')
            return False

        # and the Audience  (use claims['client_id'] if verifying an access token)
        if claims['aud'] != self.CLIENT_ID:
            logging.warning('Token was not issued for this audience')
            return False

        # now we can use the claims
        # print(claims)
        return claims
def lambda_handler(event, context):
    try:
        # TODO: write code...
        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.encode('utf-8'))

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

        claims = jwt.get_unverified_claims(token)

        # additionally we can verify the token expiration
        if time.time() > claims['exp']:
            print('Token is expired')
            return False

        # and the Audience  (use claims['client_id'] if verifying an access token)
        if claims['aud'] != app_client_id:
            print('Token was not issued for this audience')
            return False

        # now we can use the claims
        print(claims)
        return claims
    except Exception:
        return False
示例#27
0
    def verifyToken(cls, event, context):
        region = 'us-east-1'
        userpool_id = 'us-east-1_g7vZomsGY'
        app_client_id = '2pubneliqokqtnlpqdg6jl89sv'
        keys_url = 'https://cognito-idp.{}.amazonaws.com/{}/.well-known/jwks.json'.format(
            region, userpool_id)
        # instead of re-downloading the public keys every time
        # we download them only on cold start
        # https://aws.amazon.com/blogs/compute/container-reuse-in-lambda/
        response = urllib.urlopen(keys_url)
        keys = json.loads(response.read())['keys']

        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.encode('utf-8'))
        # verify the signature
        if not public_key.verify(message.encode("utf8"), decoded_signature):
            print('Signature verification failed')
            return False
        print('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']:
            print('Token is expired')
            return False
        # and the Audience  (use claims['client_id'] if verifying an access token)
        if claims['aud'] != app_client_id:
            print('Token was not issued for this audience')
            return False
        # now we can use the claims
        print(claims)
        return claims
示例#28
0
def decode_verify_jwt(token):
    response = {"status": {"code": 200, "message": ""}, "data": {}}
    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.error('Public key not found in jwks.json')
        response["status"]["code"] = 400
        response["status"]["message"] = "Public key not found in jwks.json"
        return response
    # 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.error('Signature verification failed')
        response["status"]["code"] = 400
        response["status"]["message"] = "Signature verification failed"
        return response
    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.debug('Token is expired')
        response["status"]["code"] = 400
        response["status"]["message"] = "Token is expired"
        return response

    # and the Audience  (use claims['client_id'] if verifying an access token)
    if claims['client_id'] != app_client_id:
        logger.error('Token was not issued for this audience')
        response["status"]["code"] = 400
        response["status"][
            "message"] = "Token was not issued for this audience"
        return response

    # now we can use the claims
    response["data"] = claims
    return response
示例#29
0
def lambda_handler(event, context):
    print(event)
    token = event['headers']['x-amz-security-token']
    # get the kid from the headers pterior 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.encode('utf-8'))
    # verify the signature
    if not public_key.verify(message.encode("utf8"), decoded_signature):
        print('Signature verification failed')
        return False
    print('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']:
        print('Token is expired')
        return False
    # and the Audience  (use claims['client_id'] if verifying an access token)
    if claims['aud'] != app_client_id:
        print('Token was not issued for this audience')
        return False
    # now we can use the claims
    print(claims)
    return {
        "statusCode": 200,
        "body": json.dumps(claims),
        "headers": {
            'Access-Control-Allow-Headers': 'Content-Type',
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
        }
    } 
def validate_token(token, region):
    global keys, is_cold_start, user_pool_id, app_client_id
    if is_cold_start:
        keys_url = f'https://cognito-idp.{region}.amazonaws.com/{user_pool_id}/.well-known/jwks.json'
        with urllib.request.urlopen(keys_url) as f:
            response = f.read()
        keys = json.loads(response.decode('utf-8'))['keys']
        is_cold_start = False

    # 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.encode('utf-8'))
    # verify the signature
    if not public_key.verify(message.encode("utf8"), decoded_signature):
        print('Signature verification failed')
        return False
    print('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']:
        print('Token is expired')
        return False
    # and the Audience  (use claims['client_id'] if verifying an access token)
    if claims['aud'] != app_client_id:
        print('Token was not issued for this audience')
        return False
    decoded_jwt = jwt.decode(token,
                             key=keys[key_index],
                             audience=app_client_id)
    return decoded_jwt
示例#31
0
def get_verified_token(event):
    token = event["headers"].get("Authorization") or event["queryStringParameters"].get(
        "token"
    )
    headers = jwt.get_unverified_headers(token)
    kid = headers["kid"]

    key_index = -1
    for i in range(len(JWKS_KEYS)):
        if kid == JWKS_KEYS[i]["kid"]:
            key_index = i
            break
    if key_index == -1:
        return None

    return jwt.decode(token, JWKS_KEYS[key_index], audience=COGNITO_APP_CLIENT_ID)
示例#32
0
    def fromJWT(self, token, publicKey, needOrgID, algorithm="HS256", really_dont_verify_tokens=False):
        """
    Decode a JWT into a credential. You must know the orgID for which the
    cred should have been issued, because we need to verify that it matches.

    Returns a DataWireResult with a cred member on success.
    """

        cred = None
        claims = None
        errorMessage = None

        try:
            if not publicKey:
                if not really_dont_verify_tokens:
                    errorMessage = "public key is required to decode JWT"
                else:
                    header = jwt.get_unverified_headers(token)

                    if ("typ" not in header) or (header["typ"] != "JWT"):
                        errorMessage = "malformed token (not a JWT)"
                    elif ("alg" not in header) or (header["alg"] != "HS256"):
                        errorMessage = "malformed token (not HS256)"
                    else:
                        claims = jwt.get_unverified_claims(token)
            else:
                claims = jwt.decode(
                    token, publicKey, algorithms=algorithm, audience=needOrgID, issuer="cloud-hub.datawire.io"
                )
        except JWSError as error:
            errorMessage = error.message

        if claims:
            rc = DataWireCredential.fromClaims(claims, needOrgID)

            if rc:
                cred = rc.cred
            else:
                errorMessage = rc.error

        return DataWireResult.fromErrorAndResults(error=errorMessage, cred=cred)
示例#33
0
 def test_no_alg_default_headers(self, claims, key, headers):
     token = jwt.encode(claims, key, algorithm='HS384')
     b64header, b64payload, b64signature = token.split('.')
     bad_token = b64header + '.' + b64payload
     with pytest.raises(JWTError):
         jwt.get_unverified_headers(bad_token)