def _decode_jwt_from_cookies(type): if type == 'access': cookie_key = get_access_cookie_name() else: cookie_key = get_refresh_cookie_name() token = request.cookies.get(cookie_key) if not token: raise NoAuthorizationError('Missing cookie "{}"'.format(cookie_key)) secret = _get_secret_key() algorithm = get_algorithm() token = _decode_jwt(token, secret, algorithm) if get_cookie_csrf_protect( ) and request.method in get_csrf_request_methods(): csrf_header_key = get_csrf_header_name() csrf_token_from_header = request.headers.get(csrf_header_key, None) csrf_token_from_cookie = token.get('csrf', None) # Verify the csrf tokens are present and matching if csrf_token_from_cookie is None: raise JWTDecodeError("Missing claim: 'csrf'") if not isinstance(csrf_token_from_cookie, six.string_types): raise JWTDecodeError("Invalid claim: 'csrf' (must be a string)") if csrf_token_from_header is None: raise CSRFError("Missing CSRF token in headers") if not safe_str_cmp(csrf_token_from_header, csrf_token_from_cookie): raise CSRFError("CSRF double submit tokens do not match") return token
def _decode_jwt_from_cookies(request_type): if request_type == 'access': cookie_key = config.access_cookie_name csrf_header_key = config.access_csrf_header_name else: cookie_key = config.refresh_cookie_name csrf_header_key = config.refresh_csrf_header_name encoded_token = request.cookies.get(cookie_key) if not encoded_token: raise NoAuthorizationError('Missing cookie "{}"'.format(cookie_key)) decoded_token = decode_jwt(encoded_token=encoded_token, secret=config.decode_key, algorithm=config.algorithm, csrf=config.csrf_protect) # Verify csrf double submit tokens match if required if config.csrf_protect and request.method in config.csrf_request_methods: csrf_token_in_token = decoded_token['csrf'] csrf_token_in_header = request.headers.get(csrf_header_key, None) if not csrf_token_in_header: raise CSRFError("Missing CSRF token in headers") if not safe_str_cmp(csrf_token_in_header, csrf_token_in_token): raise CSRFError("CSRF double submit tokens do not match") return decoded_token
def _decode_jwt_from_cookies(request_type): if request_type == 'access': cookie_key = config.access_cookie_name csrf_header_key = config.access_csrf_header_name csrf_field_key = config.access_csrf_field_name csrf_cookie_name = config.access_csrf_cookie_name else: cookie_key = config.refresh_cookie_name csrf_header_key = config.refresh_csrf_header_name csrf_field_key = config.refresh_csrf_field_name csrf_cookie_name = config.refresh_csrf_cookie_name encoded_token = request.cookies.get(cookie_key) if not encoded_token: raise NoAuthorizationError('Missing cookie "{}"'.format(cookie_key)) if config.csrf_protect and request.method in config.csrf_request_methods: csrf_value = request.headers.get(csrf_header_key, None) if not csrf_value and config.csrf_check_cookies: csrf_value = request.cookies.get(csrf_cookie_name, None) if not csrf_value and config.csrf_check_form: csrf_value = request.form.get(csrf_field_key, None) if not csrf_value: raise CSRFError("Missing CSRF token") else: csrf_value = None return encoded_token, csrf_value
def _decode_jwt_from_cookies(refresh): if refresh: cookie_key = config.refresh_cookie_name csrf_header_key = config.refresh_csrf_header_name csrf_field_key = config.refresh_csrf_field_name else: cookie_key = config.access_cookie_name csrf_header_key = config.access_csrf_header_name csrf_field_key = config.access_csrf_field_name encoded_token = request.cookies.get(cookie_key) if not encoded_token: raise NoAuthorizationError('Missing cookie "{}"'.format(cookie_key)) if (config.csrf_protect and request.method in config.csrf_request_methods and current_app.config["JWT_CSRF_ACCESS_PATH"] in request.url): csrf_value = request.headers.get(csrf_header_key, None) if not csrf_value and config.csrf_check_form: csrf_value = request.form.get(csrf_field_key, None) if not csrf_value: raise CSRFError("Missing CSRF token") else: csrf_value = None return encoded_token, csrf_value
def decode_jwt(encoded_token, secret, algorithm, identity_claim_key, user_claims_key, csrf_value=None): """ Decodes an encoded JWT :param encoded_token: The encoded JWT string to decode :param secret: Secret key used to encode the JWT :param algorithm: Algorithm used to encode the JWT :param identity_claim_key: expected key that contains the identity :param user_claims_key: expected key that contains the user claims :param csrf_value: Expected double submit csrf value :return: Dictionary containing contents of the JWT """ # This call verifies the ext, iat, and nbf claims data = jwt.decode(encoded_token, secret, algorithms=[algorithm]) # Make sure that any custom claims we expect in the token are present if 'jti' not in data: raise JWTDecodeError("Missing claim: jti") if identity_claim_key not in data: raise JWTDecodeError("Missing claim: {}".format(identity_claim_key)) if 'type' not in data or data['type'] not in ('refresh', 'access'): raise JWTDecodeError("Missing or invalid claim: type") if data['type'] == 'access': if 'fresh' not in data: raise JWTDecodeError("Missing claim: fresh") if user_claims_key not in data: data[user_claims_key] = {} if csrf_value: if 'csrf' not in data: raise JWTDecodeError("Missing claim: csrf") if not safe_str_cmp(data['csrf'], csrf_value): raise CSRFError("CSRF double submit tokens do not match") return data
def decode_jwt( encoded_token, secret, algorithms, identity_claim_key, user_claims_key, csrf_value=None, audience=None, leeway=0, allow_expired=False, ): """ Decodes an encoded JWT :param encoded_token: The encoded JWT string to decode :param secret: Secret key used to encode the JWT :param algorithms: Algorithms allowed to decode the token :param identity_claim_key: expected key that contains the identity :param user_claims_key: expected key that contains the user claims :param csrf_value: Expected double submit csrf value :param audience: expected audience in the JWT :param leeway: optional leeway to add some margin around expiration times :param allow_expired: Options to ignore exp claim validation in token :return: Dictionary containing contents of the JWT """ options = {} if allow_expired: options["verify_exp"] = False # This call verifies the ext, iat, nbf, and aud claims data = jwt.decode( encoded_token, secret, algorithms=algorithms, audience=audience, leeway=leeway, options=options, ) # Make sure that any custom claims we expect in the token are present if "jti" not in data: data["jti"] = None if identity_claim_key not in data: raise JWTDecodeError("Missing claim: {}".format(identity_claim_key)) if "type" not in data: data["type"] = "access" if data["type"] not in ("refresh", "access"): raise JWTDecodeError("Missing or invalid claim: type") if data["type"] == "access": if "fresh" not in data: data["fresh"] = False if user_claims_key not in data: data[user_claims_key] = {} if csrf_value: if "csrf" not in data: raise JWTDecodeError("Missing claim: csrf") if not safe_str_cmp(data["csrf"], csrf_value): raise CSRFError("CSRF double submit tokens do not match") return data
def _decode_jwt( algorithms, allow_expired, audience, csrf_value, encoded_token, identity_claim_key, issuer, leeway, secret, verify_aud, ): options = {"verify_aud": verify_aud} if allow_expired: options["verify_exp"] = False # This call verifies the ext, iat, and nbf claims # This optionally verifies the exp and aud claims if enabled decoded_token = jwt.decode( encoded_token, secret, algorithms=algorithms, audience=audience, issuer=issuer, leeway=leeway, options=options, ) # Make sure that any custom claims we expect in the token are present if identity_claim_key not in decoded_token: raise JWTDecodeError("Missing claim: {}".format(identity_claim_key)) if "type" not in decoded_token: decoded_token["type"] = "access" if decoded_token["type"] not in ("access", "refresh"): raise JWTDecodeError("Invalid token type: {}".format( decoded_token["type"])) if "fresh" not in decoded_token: decoded_token["fresh"] = False if "jti" not in decoded_token: decoded_token["jti"] = None if csrf_value: if "csrf" not in decoded_token: raise JWTDecodeError("Missing claim: csrf") if not safe_str_cmp(decoded_token["csrf"], csrf_value): raise CSRFError("CSRF double submit tokens do not match") return decoded_token
def _decode_jwt( algorithms: Iterable, allow_expired: bool, audience: Union[str, Iterable[str]], csrf_value: str, encoded_token: str, identity_claim_key: str, issuer: str, leeway: int, secret: str, verify_aud: bool, ) -> dict: options = {"verify_aud": verify_aud} if allow_expired: options["verify_exp"] = False # This call verifies the ext, iat, and nbf claims # This optionally verifies the exp and aud claims if enabled decoded_token = jwt.decode( encoded_token, secret, algorithms=algorithms, audience=audience, issuer=issuer, leeway=leeway, options=options, ) # Make sure that any custom claims we expect in the token are present if identity_claim_key not in decoded_token: raise JWTDecodeError("Missing claim: {}".format(identity_claim_key)) if "type" not in decoded_token: decoded_token["type"] = "access" if "fresh" not in decoded_token: decoded_token["fresh"] = False if "jti" not in decoded_token: decoded_token["jti"] = None if csrf_value: if "csrf" not in decoded_token: raise JWTDecodeError("Missing claim: csrf") if not compare_digest(decoded_token["csrf"], csrf_value): raise CSRFError("CSRF double submit tokens do not match") return decoded_token
def decode_jwt(encoded_token, secret, algorithm, identity_claim_key, user_claims_key, csrf_value=None, audience=None, leeway=0, allow_expired=False, verify_audience=False): """ Decodes an encoded JWT :param encoded_token: The encoded JWT string to decode :param secret: Secret key used to encode the JWT :param algorithm: Algorithm used to encode the JWT :param identity_claim_key: expected key that contains the identity :param user_claims_key: expected key that contains the user claims :param csrf_value: Expected double submit csrf value :param audience: expected audience in the JWT :param leeway: optional leeway to add some margin around expiration times :param allow_expired: Options to ignore exp claim validation in token :param verify_audience: Options to ignore aud claim validation in token :return: Dictionary containing contents of the JWT """ options = {} if allow_expired: options['verify_exp'] = False options['verify_aud'] = verify_audience # This call verifies the ext, iat, nbf, and aud claims data = jwt.decode(encoded_token, secret, algorithms=[algorithm], audience=audience, leeway=leeway, options=options) # Make sure that any custom claims we expect in the token are present if 'jti' not in data: data['jti'] = None if identity_claim_key not in data: raise JWTDecodeError("Missing claim: {}".format(identity_claim_key)) if 'type' not in data: data['type'] = 'access' if data['type'] not in ('refresh', 'access'): raise JWTDecodeError("Missing or invalid claim: type") if data['type'] == 'access': if 'fresh' not in data: data['fresh'] = False if user_claims_key not in data: data[user_claims_key] = {} if csrf_value: if 'csrf' not in data: raise JWTDecodeError("Missing claim: csrf") if not safe_str_cmp(data['csrf'], csrf_value): raise CSRFError("CSRF double submit tokens do not match") return data