fix(security): improve api key and jwt validation handling
This commit is contained in:
parent
574d82f3c4
commit
1c6c45465f
2 changed files with 21 additions and 7 deletions
17
api.py
17
api.py
|
|
@ -278,18 +278,21 @@ def get_auth_schemes_for_user(swagger_user: dict) -> dict:
|
|||
allowed_tags = swagger_user.get("allowed_tags")
|
||||
|
||||
if not allowed_tags:
|
||||
# Admin complet
|
||||
return {
|
||||
"HTTPBearer": {
|
||||
"type": "http",
|
||||
"scheme": "bearer",
|
||||
"bearerFormat": "JWT",
|
||||
"description": "Authentification JWT pour utilisateurs (POST /auth/login)",
|
||||
"description": "🎫 Authentification JWT pour utilisateurs (POST /auth/login). "
|
||||
"Utilisez SOIT JWT SOIT API Key, pas les deux.",
|
||||
},
|
||||
"ApiKeyAuth": {
|
||||
"type": "apiKey",
|
||||
"in": "header",
|
||||
"name": "X-API-Key",
|
||||
"description": "Clé API pour intégrations externes (format: sdk_live_xxx)",
|
||||
"description": " Clé API pour intégrations externes (format: sdk_live_xxx). "
|
||||
"Utilisez SOIT JWT SOIT API Key, pas les deux.",
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -300,14 +303,16 @@ def get_auth_schemes_for_user(swagger_user: dict) -> dict:
|
|||
"type": "http",
|
||||
"scheme": "bearer",
|
||||
"bearerFormat": "JWT",
|
||||
"description": "Authentification JWT pour utilisateurs (POST /auth/login)",
|
||||
"description": "🎫 Authentification JWT pour utilisateurs (POST /auth/login). "
|
||||
"Utilisez SOIT JWT SOIT API Key, pas les deux.",
|
||||
}
|
||||
|
||||
schemes["ApiKeyAuth"] = {
|
||||
"type": "apiKey",
|
||||
"in": "header",
|
||||
"name": "X-API-Key",
|
||||
"description": "Clé API pour intégrations externes (format: sdk_live_xxx)",
|
||||
"description": " Clé API pour intégrations externes (format: sdk_live_xxx). "
|
||||
"Utilisez SOIT JWT SOIT API Key, pas les deux.",
|
||||
}
|
||||
|
||||
return schemes
|
||||
|
|
@ -483,7 +488,9 @@ async def custom_swagger_ui(request: Request):
|
|||
"displayRequestDuration": True,
|
||||
"filter": True,
|
||||
"tryItOutEnabled": True,
|
||||
"docExpansion": "list", # Meilleure UX
|
||||
"docExpansion": "list",
|
||||
# CORRECTIF : Ne pas pré-remplir les credentials
|
||||
"preAuthorizeApiKey": False,
|
||||
},
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -158,14 +158,18 @@ class ApiKeyMiddlewareHTTP(BaseHTTPMiddleware):
|
|||
auth_header = request.headers.get("Authorization")
|
||||
api_key_header = request.headers.get("X-API-Key")
|
||||
|
||||
# CORRECTIF : Nettoyer et valider la clé API
|
||||
if api_key_header:
|
||||
api_key_header = api_key_header.strip()
|
||||
# Si la clé est vide ou juste des espaces, la considérer comme absente
|
||||
if not api_key_header or api_key_header == "":
|
||||
api_key_header = None
|
||||
|
||||
# Vérifier si c'est un token JWT Bearer
|
||||
if auth_header and auth_header.startswith("Bearer "):
|
||||
token = auth_header.split(" ")[1].strip()
|
||||
token = auth_header.split(" ", 1)[1].strip()
|
||||
|
||||
# CORRECTIF : Vérifier si c'est une API Key envoyée par erreur dans Authorization
|
||||
if token.startswith("sdk_live_"):
|
||||
logger.warning(
|
||||
"⚠️ API Key envoyée dans Authorization au lieu de X-API-Key"
|
||||
|
|
@ -174,16 +178,19 @@ class ApiKeyMiddlewareHTTP(BaseHTTPMiddleware):
|
|||
request, token, path, method, call_next
|
||||
)
|
||||
|
||||
# C'est un JWT valide, déléguer à FastAPI
|
||||
logger.debug(f"🎫 JWT détecté pour {method} {path} → délégation à FastAPI")
|
||||
request.state.authenticated_via = "jwt"
|
||||
return await call_next(request)
|
||||
|
||||
# CORRECTIF : Si une clé API est présente ET non vide, la traiter
|
||||
if api_key_header:
|
||||
logger.debug(f"🔑 API Key détectée pour {method} {path}")
|
||||
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
|
||||
)
|
||||
|
||||
# Aucune authentification fournie, déléguer à FastAPI qui renverra 401
|
||||
logger.debug(f"❌ Aucune auth pour {method} {path} → délégation à FastAPI")
|
||||
return await call_next(request)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue