auth: make session binding optional, enforce WebAuthn credential ownership
- Make session_id parameter optional in validate_token — only enforced when provided, allowing WebSocket auth which cannot carry custom headers - Remove decode_token round-trip from daemon WS handler - Override WebAuthn registration username from JWT user_ctx to prevent users from registering credentials under another user's account - Frontend no longer sends username for WebAuthn registration - Redirect to login on 401 after token refresh fails for POST requests - Remove redundant auth session check from login page load - Add tests for session_id semantics and WebAuthn ownership guard
This commit is contained in:
+5
-10
@@ -290,9 +290,10 @@ def validate_token(
|
||||
token_string: The JWT token string.
|
||||
token_type: Expected token type ("access" or "refresh").
|
||||
session_id: Must match the ``session_id`` claim in the token payload.
|
||||
Required for access tokens — prevents a stolen token from being
|
||||
usable without the originating session. Ignored for refresh tokens
|
||||
which carry no ``session_id`` claim.
|
||||
When provided, enforces session binding to prevent a stolen token
|
||||
from being usable without the originating session. When ``None``,
|
||||
the check is skipped (used by WebSocket auth which cannot carry
|
||||
the session ID header).
|
||||
|
||||
Returns:
|
||||
Payload dict including permissions, or None if invalid/blacklisted.
|
||||
@@ -302,13 +303,7 @@ def validate_token(
|
||||
return None
|
||||
if payload.get("type") != token_type:
|
||||
return None
|
||||
if token_type == "access" and session_id != payload.get("session_id"):
|
||||
return None
|
||||
if (
|
||||
token_type != "access"
|
||||
and session_id
|
||||
and payload.get("session_id") != session_id
|
||||
):
|
||||
if session_id is not None and session_id != payload.get("session_id"):
|
||||
return None
|
||||
|
||||
jti = payload.get("jti")
|
||||
|
||||
Reference in New Issue
Block a user