def decorated_function(*args, **kwargs): # Initially valid_permissions = True valid_roles = True try: decoded = __frontegg.frontegg.decode_jwt(request.headers.get('Authorization')) g.user = decoded # Validate roles if role_keys is not None: logger.info('will check if entity has one of required roles') valid_roles = any( role in decoded['roles'] for role in role_keys) if permission_keys is not None: logger.info('will check if entity has one of required permissions') valid_permissions = any( permission in decoded['permissions'] for permission in permission_keys) except Exception as e: logger.debug('something went wrong while validating roles and permissions, ' + str(e)) abort(401) if not valid_permissions or not valid_roles: logger.info('entity does not have required role and permissions') abort(403) return logger.info('entity passed authentication middleware') return f(*args, **kwargs)
def authentication_middleware(request: Request): try: __frontegg.frontegg.decode_jwt(request.headers.get('Authorization')) logger.info('JWT token verified') return None except Exception as e: logger.debug('could not verify JWT token, ' + str(e), ) raise UnauthenticatedException()
def context_provider(request: Request): try: user = __frontegg.frontegg.decode_jwt( request.headers.get('Authorization')) logger.debug('get user from JWT' + str(user)) return FronteggContext(user.get('sub'), user.get('tenantId')) except Exception as e: logger.debug('could not get user from JWT, ' + str(e)) logger.info('will send default tenant-id and user-id') return FronteggContext('user-id', 'tenant-id')
def decode_jwt(self, authorization_header, verify: typing.Optional[bool] = True): if not authorization_header: raise InvalidTokenError('Authorization headers is missing') logger.debug('found authorization header: ' + str(authorization_header)) jwt_token = authorization_header.replace('Bearer ', '') public_key = self.get_public_key() logger.debug('got public key' + str(public_key)) decoded = self.__get_jwt_data(jwt_token, verify, public_key) logger.info('jwt was decoded successfully') logger.debug('JWT value - ' + str(decoded)) return decoded
def proxy_request(self, request, method: str, path: str, host: str, params: dict, body: typing.Optional[any], cookies: typing.Optional[dict] = None, headers: typing.Optional[dict] = {}): if not request: raise Exception('request is required') if not method: raise Exception('method is required') if not path: raise Exception('path is required') path_without_frontegg = path.replace( '/' + self.middleware_prefix, '', 1).replace(self.middleware_prefix, '', 1) logger.info('removed path prefix before sending to frontegg, new path - %s', path_without_frontegg) public_route = self.is_public_route( path_without_frontegg, params, method) logger.info('route is %s public route', '' if public_route else 'not') if self.authentication_middleware is not None and not public_route: try: logger.info('will validate user authentication') self.authentication_middleware(request) except HttpException as response: logger.info('failed to authorize entity') return response except Exception as e: logger.info('something went wrong, could not run authentication middleware') logger.debug('auth middleware error - %s', str(e)) return HttpException('Something went wrong', 500) url = urljoin(frontegg_urls.base_url, path_without_frontegg) headers = self.clean_request_headers(headers, host) headers = self.set_context(headers, request) logger.info('adjusted headers before proxying request to frontegg') logger.debug('new headers - %s', str(headers)) if self.should_refresh_vendor_token: logger.info('refresh vendor token is required, will refresh token') self.refresh_vendor_token() logger.info('will proxy request to frontegg') logger.debug('request data: method=%s, url=%s,cookies=%s, body=%s, params=%s, headers=%s', method, url, str(cookies), str(body), str(params), str(headers)) response = self.vendor_session_request.request( method, url, headers=headers, cookies=cookies, data=body, params=params ) logger.info('got response from frontegg') response.headers = self.clean_response_headers(response.headers) response.cookies = self.get_cookies(response.headers) return response