diff --git a/src/titiler/application/titiler/application/main.py b/src/titiler/application/titiler/application/main.py index 39d6ca799..4a262408c 100644 --- a/src/titiler/application/titiler/application/main.py +++ b/src/titiler/application/titiler/application/main.py @@ -151,7 +151,7 @@ ) if api_settings.jwt_secret: - app.add_middleware(JWTAuthenticationMiddleware, secret=api_settings.jwt_secret) + app.add_middleware(JWTAuthenticationMiddleware, secret=api_settings.jwt_secret, user_key="id") if api_settings.debug: logging.basicConfig(level=logging.DEBUG) diff --git a/src/titiler/application/titiler/application/settings.py b/src/titiler/application/titiler/application/settings.py index 617612b26..8c3273594 100644 --- a/src/titiler/application/titiler/application/settings.py +++ b/src/titiler/application/titiler/application/settings.py @@ -1,5 +1,5 @@ """Titiler API settings.""" - +import os from pydantic import field_validator from pydantic_settings import BaseSettings, SettingsConfigDict @@ -20,7 +20,7 @@ class ApiSettings(BaseSettings): lower_case_query_parameters: bool = False fake_https: bool = False - jwt_secret: str = "" + jwt_secret: str = os.getenv("OVISION_TOKEN", "") model_config = SettingsConfigDict(env_prefix="TITILER_API_", env_file=".env") diff --git a/src/titiler/core/titiler/core/middleware.py b/src/titiler/core/titiler/core/middleware.py index 09106fa0a..d8549ef9f 100644 --- a/src/titiler/core/titiler/core/middleware.py +++ b/src/titiler/core/titiler/core/middleware.py @@ -147,11 +147,11 @@ async def send_wrapper(message: Message): except: user = None if user: - log['user'] = user - log['status'] = message["status"] + log["user"] = user + log["status"] = message["status"] if self.headers: - log['res.headers'] = message["headers"] + log["res.headers"] = message["headers"] self.logger.debug(log) await send(message) @@ -159,7 +159,6 @@ async def send_wrapper(message: Message): await self.app(scope, receive, send_wrapper) - class LowerCaseQueryStringMiddleware: """Middleware to make URL parameters case-insensitive. taken from: https://github.com/tiangolo/fastapi/issues/826 @@ -212,9 +211,11 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send): class JWTAuthenticationMiddleware: - """Middleware to authentication with jwt""" + """Middleware for authentication with jwt""" - def __init__(self, app: ASGIApp, secret: str, user_key="user", algorithms: List[str]=None) -> None: + def __init__( + self, app: ASGIApp, secret: str, user_key="user", algorithms: List[str] = None + ) -> None: """Init Middleware. Args: @@ -224,8 +225,9 @@ def __init__(self, app: ASGIApp, secret: str, user_key="user", algorithms: List[ algorithms (List[str]): algorithms for decode jwt. default ["HS512"] """ if algorithms is None: - algorithms = ["HS512"] + algorithms = ["HS256"] from fastapi.security import HTTPBearer + self.app = app self.secret = secret self.http_bearer = HTTPBearer(bearerFormat="jwt", auto_error=False) @@ -233,26 +235,32 @@ def __init__(self, app: ASGIApp, secret: str, user_key="user", algorithms: List[ self.user_key = user_key async def __call__(self, scope: Scope, receive: Receive, send: Send): - async def response401(message: str="Not authenticated"): - response = JSONResponse(content={"detail": message}, - status_code=starlette.status.HTTP_401_UNAUTHORIZED) + async def response401(message: str = "Not authenticated"): + response = JSONResponse( + content={"detail": message}, + status_code=starlette.status.HTTP_401_UNAUTHORIZED, + ) await response(scope, receive, send) + """Handle call.""" if scope["type"] == "http": request = Request(scope) - credentials = await self.http_bearer(request) - if not credentials: + + access_token = request.query_params.get("access_token") + if not access_token: await response401("access token is required") return try: - payload = jwt.decode(credentials.credentials, self.secret, algorithms=self.algorithms) + payload = jwt.decode( + access_token, self.secret, algorithms=self.algorithms + ) except jwt.DecodeError as e: await response401("unsupported token") except jwt.InvalidTokenError as e: await response401("invalid token") return user = payload[self.user_key] - scope['auth'] = credentials.credentials - scope['user'] = user + scope["auth"] = access_token + scope["user"] = user await self.app(scope, receive, send)