fix(security): improve auth handling and logging in middleware

This commit is contained in:
Fanilo-Nantenaina 2026-01-20 19:14:00 +03:00
parent 5eec115d1d
commit a7457c3979
2 changed files with 17 additions and 21 deletions

View file

@ -112,6 +112,7 @@ class ApiKeyMiddlewareHTTP(BaseHTTPMiddleware):
"/health", "/health",
"/auth", "/auth",
"/api-keys/verify", "/api-keys/verify",
"/universign/webhook",
] ]
def _is_excluded_path(self, path: str) -> bool: def _is_excluded_path(self, path: str) -> bool:
@ -137,6 +138,12 @@ class ApiKeyMiddlewareHTTP(BaseHTTPMiddleware):
auth_header = request.headers.get("Authorization") auth_header = request.headers.get("Authorization")
api_key_header = request.headers.get("X-API-Key") api_key_header = request.headers.get("X-API-Key")
if api_key_header:
logger.debug(f"🔑 API Key détectée pour {method} {path}")
return await self._handle_api_key_auth(
request, api_key_header, path, method, call_next
)
if auth_header and auth_header.startswith("Bearer "): if auth_header and auth_header.startswith("Bearer "):
token = auth_header.split(" ")[1] token = auth_header.split(" ")[1]
@ -144,27 +151,16 @@ class ApiKeyMiddlewareHTTP(BaseHTTPMiddleware):
logger.warning( logger.warning(
" API Key envoyée dans Authorization au lieu de X-API-Key" " API Key envoyée dans Authorization au lieu de X-API-Key"
) )
api_key_header = token return await self._handle_api_key_auth(
else: request, token, path, method, call_next
logger.debug(f" JWT détecté pour {method} {path}") )
return await call_next(request)
if api_key_header: logger.debug(f"🎫 JWT détecté pour {method} {path} → délégation à FastAPI")
logger.debug(f" API Key détectée pour {method} {path}") request.state.authenticated_via = "jwt"
return await self._handle_api_key_auth( return await call_next(request)
request, api_key_header, path, method, call_next
)
logger.warning(f" Aucune authentification: {method} {path}") logger.debug(f" Aucune auth pour {method} {path} → délégation à FastAPI")
return JSONResponse( return await call_next(request)
status_code=status.HTTP_401_UNAUTHORIZED,
content={
"detail": "Authentification requise",
"hint": "Utilisez 'X-API-Key: sdk_live_xxx' ou 'Authorization: Bearer <jwt>'",
"path": path,
},
headers={"WWW-Authenticate": 'Bearer realm="API", charset="UTF-8"'},
)
async def _handle_api_key_auth( async def _handle_api_key_auth(
self, self,
@ -196,7 +192,7 @@ class ApiKeyMiddlewareHTTP(BaseHTTPMiddleware):
is_allowed, rate_info = await service.check_rate_limit(api_key_obj) is_allowed, rate_info = await service.check_rate_limit(api_key_obj)
if not is_allowed: if not is_allowed:
logger.warning(f"⚠️ Rate limit: {api_key_obj.name}") logger.warning(f" Rate limit: {api_key_obj.name}")
return JSONResponse( return JSONResponse(
status_code=status.HTTP_429_TOO_MANY_REQUESTS, status_code=status.HTTP_429_TOO_MANY_REQUESTS,
content={"detail": "Rate limit dépassé"}, content={"detail": "Rate limit dépassé"},

View file

@ -162,7 +162,7 @@ async def create_api_key(
logger.info(" Endpoints: Tous (aucune restriction)") logger.info(" Endpoints: Tous (aucune restriction)")
logger.info("=" * 70) logger.info("=" * 70)
logger.info("⚠️ SAUVEGARDEZ CETTE CLÉ - Elle ne sera plus affichée !") logger.info(" SAUVEGARDEZ CETTE CLÉ - Elle ne sera plus affichée !")
logger.info("=" * 70) logger.info("=" * 70)