feat(07.4-02): add fgp validation block to get_current_user in deps/auth.py
- Add `import hmac` to deps/auth.py imports block - Insert fgp check after user_nbf block: extract fgp_claim from payload, skip if empty (migration grace for pre-7.4 tokens, D-06), recompute fgp_actual via auth_service._compute_fgp, compare with hmac.compare_digest - Mismatch raises HTTP 401 "Token fingerprint mismatch" (D-03) - Block placed outside try/except (pure computation, no I/O, no fail-open)
This commit is contained in:
@@ -20,6 +20,7 @@ Usage in route handlers:
|
||||
):
|
||||
...
|
||||
"""
|
||||
import hmac
|
||||
import logging
|
||||
import uuid
|
||||
|
||||
@@ -84,6 +85,24 @@ async def get_current_user(
|
||||
_logger.warning("Redis user_nbf check failed (fail-open): %s", exc)
|
||||
# ── end user_nbf check ──────────────────────────────────────────────────────
|
||||
|
||||
# ── fgp check (D-06, Phase 7.4) ────────────────────────────────────────────
|
||||
# Validates the fgp claim embedded by create_access_token. Empty claim means
|
||||
# the token predates Phase 7.4 — allow gracefully (migration window, D-06).
|
||||
# NOT wrapped in try/except: _compute_fgp is pure computation with no I/O.
|
||||
fgp_claim = payload.get("fgp", "")
|
||||
if fgp_claim:
|
||||
fgp_actual = auth_service._compute_fgp(
|
||||
request.headers.get("User-Agent", ""),
|
||||
request.headers.get("Accept-Language", ""),
|
||||
)
|
||||
if not hmac.compare_digest(fgp_claim, fgp_actual):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="Token fingerprint mismatch",
|
||||
headers={"WWW-Authenticate": "Bearer"},
|
||||
)
|
||||
# ── end fgp check ───────────────────────────────────────────────────────────
|
||||
|
||||
try:
|
||||
user_uuid = uuid.UUID(payload["sub"])
|
||||
except (KeyError, ValueError) as exc:
|
||||
|
||||
Reference in New Issue
Block a user