def decorated(*args, **kwargs): token = request.headers.get("token") if not token: raise InvalidTokenError("Token is missing. Please login again") if not TokenService.decodeToken(token).get("group_id") == "2": raise InvalidTokenError("Token is invalid. Please login again") return fn(*args, **kwargs)
def decorated(*args, **kwargs): token = request.headers.get("token") if not token: raise InvalidTokenError("Token is missing. Please login again") validity = TokenService.verifyToken(token) if not validity[0]: raise InvalidTokenError(validity[1]) return fn(*args, **kwargs)
def _request_x5c(key_identifier: str, identity_provider_url: str) -> str: keys = requests.get(identity_provider_url) if not keys: raise InvalidTokenError(f"Identify provider cannot be reached: {keys.text}") keys = keys.json().get("keys", []) keys = {key["kid"]: key["x5c"][0] for key in keys} if key_identifier not in keys: raise InvalidTokenError( f"{key_identifier} is not a valid key identifier. Valid ones are {list(keys)}." ) return keys[key_identifier]
def get_jwk_for_token(self, token): unverified_header = jwt.get_unverified_header(token) try: token_kid = unverified_header['kid'] except KeyError: raise InvalidTokenError("Key ID header parameter is missing") for jwk in self.get_jwk_set()['keys']: if jwk['kid'] == token_kid: return jwk raise InvalidTokenError("no key found")
def decorated_function(*args, **kwargs): token = request.headers['authorization'] if not token: raise InvalidTokenError('Invalid token') parts = token.split(' ') if len(parts) > 2: raise InvalidTokenError('Invalid token') [scheme, token] = parts if scheme.strip() != 'Bearer': raise InvalidSignatureError('Invalid token signature') try: jwt.decode(token, variables.SECRET_KEY) return func(*args, **kwargs) except DecodeError: raise DecodeError('Token could not be decoded')
def decode(jwt_token: str) -> (dict, dict): """ Decode base64 encoded token and return JSON decoded header and body as a tuple. :raises InvalidTokenError """ if not jwt_token: raise InvalidTokenError("JWT Token is mandatory.") if jwt_token.count(".") < 2: raise InvalidTokenError( "Invalid JWT Token (header, body and signature must be separated by dots)." ) (jwt_header, jwt_body, jwt_signature) = jwt_token.split(".", maxsplit=2) return _to_json(jwt_header), _to_json(jwt_body)
def validate_user(email, password): """ Validates user logging in :param email: user email :param password: user password :return: JSON web token """ user = db.users.find_one({'email': email}) if user is None: raise LookupError('User account not found') hashed = user['password'].encode('utf-8') if bcrypt.hashpw(password.encode('utf-8'), hashed) == hashed: try: token = jwt.encode({'_id': str(user['_id'])}, config.SECRET_KEY, algorithm='HS256') return token except Exception: raise InvalidTokenError("Error creating JWToken") else: raise AssertionError("Incorrect password")
def wrapper(*args, **kwargs): logger = getLogger("jwt") token = None if JWT_HEADER_KEY in request.headers: token = request.headers[JWT_HEADER_KEY] if not token: return abort(401) try: token_data = jwt.decode(token, os.environ.get("FLASK_SECRET")) user_id = token_data.get("userId") if not user_id: raise (InvalidKeyError("userId")) current_user = User.query.get(user_id) if not current_user: raise InvalidTokenError( f"user not found for user_id {user_id}") expiration = token_data.get("expiration") if not expiration: raise (InvalidKeyError("expiration")) if datetime.strptime(expiration, "%Y-%m-%d") < datetime.now(): return {"message": "Login expired"}, 401 # survived the gauntlet! return func(*args, **kwargs) except ( InvalidTokenError, InvalidKeyError, ) as e: logger.error(f"invalid auth: {e}") return abort(401)
def _validate_claims(self, payload, options, audience=None, issuer=None, leeway=0, **kwargs): if options.get("exp_max_s") is not None: if "verify_expiration" in kwargs and not kwargs.get("verify_expiration"): raise ValueError("exp_max_s option implies verify_expiration") options["verify_exp"] = True # Do all of the other checks super(_StrictJWT, self)._validate_claims( payload, options, audience, issuer, leeway, **kwargs ) now = timegm(datetime.utcnow().utctimetuple()) self._reject_future_iat(payload, now, leeway) if "exp" in payload and options.get("exp_max_s") is not None: # Validate that the expiration was not more than exp_max_s seconds after the issue time # or in the absence of an issue time, more than exp_max_s in the future from now # This will work because the parent method already checked the type of exp expiration = datetime.utcfromtimestamp(int(payload["exp"])) max_signed_s = options.get("exp_max_s") start_time = datetime.utcnow() if "iat" in payload: start_time = datetime.utcfromtimestamp(int(payload["iat"])) if expiration > start_time + timedelta(seconds=max_signed_s): raise InvalidTokenError( "Token was signed for more than %s seconds from %s", max_signed_s, start_time )
def decode_jwt_token(token): unverified_header = jwt.get_unverified_header(token) unverified_claims = jwt.decode(token, verify=False) if unverified_header.get(claims.KEY_ID): unverified_key_id = six.text_type(unverified_header.get(claims.KEY_ID)) else: unverified_key_id = None if claims.ISSUER not in unverified_claims: raise MissingRequiredClaimError(claims.ISSUER) unverified_issuer = six.text_type(unverified_claims[claims.ISSUER]) if api_settings.ACCEPTED_ISSUERS is not None and unverified_issuer not in api_settings.ACCEPTED_ISSUERS: raise InvalidIssuerError('Invalid issuer') public_key, key_id = get_public_key_and_key_id(issuer=unverified_issuer, key_id=unverified_key_id) options = { 'verify_exp': api_settings.VERIFY_EXPIRATION, 'verify_aud': True, 'verify_iss': True, } payload = jwt.decode( jwt=token, key=public_key, verify=api_settings.VERIFY_SIGNATURE, algorithms=api_settings.DECODE_ALGORITHMS or [api_settings.ENCODE_ALGORITHM], options=options, leeway=api_settings.EXPIRATION_LEEWAY, audience=api_settings.IDENTITY, issuer=unverified_issuer, ) if payload.get(claims.TOKEN) not in (claims.TOKEN_SESSION, claims.TOKEN_AUTHORIZATION): raise InvalidTokenError('Unknown token type') if payload.get(claims.ISSUER) != api_settings.IDENTITY and payload.get(claims.TOKEN) != claims.TOKEN_AUTHORIZATION: raise InvalidTokenError('Only authorization tokens are accepted from other issuers') if not payload.get(claims.SESSION_ID): raise MissingRequiredClaimError('Session ID is missing.') if not payload.get(claims.USER_ID): raise MissingRequiredClaimError('User ID is missing.') return payload
def validate_jwt_token(token, user=None): """ Validate the given auth/refresh JWT token for given user. It run all security checks to invalidate token if required like 1. User is not active 2. Password reset of user :param token: :param user: :return: an user instance """ # TODO : refactor this method # it's unverified payload payload = jwt.decode(token, None, False) username = jwt_get_username_from_payload_handler(payload) if username is None: raise InvalidTokenError( "'username' field value in token payload is null or not set") if user is None: from src.apis.models.user import User try: user = User.objects.get_by_natural_key(username) except User.DoesNotExist: raise InvalidTokenError(f"No user found for username '{username}'") if getattr(user, "username") != username: raise InvalidTokenError( "'username' in token payload and subject user instance is not " "matched") # ----------- 1) User account is set inactive --------------------------- if not user.is_active: raise InvalidTokenError("Invalid token") # ----------- 2) User changed password ---------------------------------- # Invalidate the token, if user's password is changed after token is # issued token_iat = payload.get("orig_iat") # time is in epoch # user_password_changed_at = dt_to_epoch(user.last_password_change) # if user_password_changed_at and user_password_changed_at > token_iat: # raise InvalidTokenError("Invalid token") return user
def test_should_return_401_if_load_account_by_id_raise_jwt_exception( mock_load: MagicMock, mock_get_collection: MagicMock, sut: AuthMiddleware): mock_load.side_effect = InvalidTokenError() mock_get_collection.return_value = mongomock.MongoClient().db.collection http_response = sut.handle( HttpRequest(headers={"x-access-token": "any_token"}, body=None)) assert http_response.status_code == 401 assert http_response.body["message"] == "Unauthorized"
def get(json_body: dict, key: str, description: str = None) -> str: """ Return value for a given key stored in JSON body. :raises InvalidTokenError in case key does not exists. """ value = json_body.get(key) if value is None: raise InvalidTokenError( f"No {description if description else key} in JSON body.") return value
def decode_jwt_token(token): unverified_header = jwt.get_unverified_header(token) unverified_claims = jwt.decode(token, verify=False) if unverified_header.get(claims.KEY_ID): unverified_key_id = str(unverified_header.get(claims.KEY_ID)) else: unverified_key_id = None if claims.ISSUER not in unverified_claims: raise MissingRequiredClaimError(claims.ISSUER) unverified_issuer = str(unverified_claims[claims.ISSUER]) if api_settings.ACCEPTED_ISSUERS is not None and unverified_issuer not in api_settings.ACCEPTED_ISSUERS: raise InvalidIssuerError("Invalid issuer") public_key, key_id = get_public_key_and_key_id(issuer=unverified_issuer, key_id=unverified_key_id) options = { "verify_exp": api_settings.VERIFY_EXPIRATION, "verify_iss": api_settings.VERIFY_ISSUER, "verify_aud": api_settings.VERIFY_AUDIENCE, } payload = jwt.decode( jwt=token, key=public_key, verify=api_settings.VERIFY_SIGNATURE, algorithms=api_settings.DECODE_ALGORITHMS or [api_settings.ENCODE_ALGORITHM], options=options, leeway=api_settings.EXPIRATION_LEEWAY, audience=api_settings.IDENTITY, issuer=unverified_issuer, ) if payload.get(claims.TOKEN) not in (claims.TOKEN_SESSION, claims.TOKEN_AUTHORIZATION): raise InvalidTokenError("Unknown token type") if not payload.get(claims.SESSION_ID): raise MissingRequiredClaimError("Session ID is missing.") if not payload.get(claims.USER_ID): raise MissingRequiredClaimError("User ID is missing.") return payload
def do_GET(self): if self.path == "/healthz": self.send_response(200) self.send_header("Content-type", "text/plain") self.end_headers() return try: authorization = self.headers.get("authorization") auth_header = authorization.split() if auth_header[0].lower() != 'bearer' or len(auth_header) == 1: self.end_headers() return token = auth_header[1] decoded = jwt.decode( token, public_key, audience=url + '/resources', issuer=url, algorithms=['RS256']) #, options={'verify_exp': False}) scope_claims = decoded['scope'] if valid_scopes: if not any(val in scope_claims for val in valid_scopes): raise InvalidTokenError('Invalid scope ' + str(scope_claims) + ' not in ' + str(valid_scopes)) self.send_response(200) self.send_header("Content-type", "text/plain") for key, value in decoded.items(): self.send_header("X-JWT-" + key, str(value)) self.end_headers() self.wfile.write(bytes(str(decoded), "utf8")) except Exception as e: self.send_response(401) self.end_headers() self.wfile.write(bytes(str(e), "utf8")) return
def __init__(self, api, app=None): ''' :param api: Instance of a flask_restplus Api that has been associated with app :param app: Instance of flask application or blueprint ''' self.api = api super(self.__class__, self).__init__(app) # https://github.com/vimalloc/flask-jwt-extended/issues/86 self._set_error_handler_callbacks(api) # As a result of https://github.com/noirbizarre/flask-restplus/issues/421 we must register # the invalid token error handler for each sub-class of jwt.exceptions.InvalidTokenError def handle_invalid_token_error(e): return self._invalid_token_callback(str(e)) for subclass in InvalidTokenError.__subclasses__(): (api.errorhandler(subclass))(handle_invalid_token_error) # Override default error callbacks self.expired_token_loader(expired_token_callback) self.invalid_token_loader(invalid_token_callback) self.unauthorized_loader(unauthorized_callback)
def verify_sub(self, sub): if sub is None: raise InvalidTokenError('invalid sub') return True
def verify_jti(self, jti): if jti is None: raise InvalidTokenError('invalid jti') return True
def get_jwk(kid, jwks): for jwk in jwks.get('keys', []): if jwk.get('kid') == kid: return jwk raise InvalidTokenError('JWK not found for kid={0}'.format(kid, str(jwks)))