modcomms/backend/app/dependencies/auth.py
michael ba9c0ebde3 Reduce auth logging verbosity: INFO → DEBUG
All routine MSAL token verification logs now use DEBUG level so they
don't flood the console on every polling request.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 16:13:25 -06:00

74 lines
2.7 KiB
Python
Executable file

"""
FastAPI authentication dependencies.
Provides dependency functions for securing REST endpoints with Azure AD token verification.
"""
import logging
from typing import Optional
from fastapi import Header, HTTPException, status
from app.config import settings
from app.services.auth_service import verify_access_token
logger = logging.getLogger(__name__)
async def get_current_user(authorization: Optional[str] = Header(None)) -> dict:
"""
FastAPI dependency to verify the access token and return user claims.
Use as a dependency on protected endpoints:
@app.get("/protected")
async def protected_route(user: dict = Depends(get_current_user)):
return {"message": f"Hello {user.get('name')}"}
Args:
authorization: The Authorization header value (Bearer <token>)
Returns:
The token claims dict containing user information
Raises:
HTTPException: 401 if token is missing or invalid
"""
logger.debug("[MSAL Backend] get_current_user dependency called")
# If auth is disabled, return mock user immediately
if settings.DISABLE_AUTH:
logger.debug("[MSAL Backend] Auth disabled - returning mock user")
return {"sub": "dev-user", "name": "Development User", "preferred_username": "dev@localhost"}
if not authorization:
logger.warning("[MSAL Backend] Missing authorization header")
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Missing authorization header",
headers={"WWW-Authenticate": "Bearer"},
)
logger.debug(f"[MSAL Backend] Authorization header present, length: {len(authorization)}")
# Extract token from "Bearer <token>" format
parts = authorization.split()
if len(parts) != 2 or parts[0].lower() != "bearer":
logger.warning(f"[MSAL Backend] Invalid auth header format: {parts[0] if parts else 'empty'}")
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid authorization header format. Expected: Bearer <token>",
headers={"WWW-Authenticate": "Bearer"},
)
token = parts[1]
logger.debug("[MSAL Backend] Extracted Bearer token, calling verify_access_token...")
claims = await verify_access_token(token)
if not claims:
logger.warning("[MSAL Backend] Token verification failed - returning 401")
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid or expired token",
headers={"WWW-Authenticate": "Bearer"},
)
logger.debug(f"[MSAL Backend] Authentication successful for: {claims.get('name', 'unknown')}")
return claims