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:
+3
-8
@@ -373,7 +373,7 @@ async def _handle_ws(request: web.Request) -> web.Response:
|
||||
1. WebSocket subprotocol header (Sec-WebSocket-Protocol: "Bearer <token>")
|
||||
2. X-Auth-Token header (nginx-injected)
|
||||
"""
|
||||
from lib.auth import decode_token, validate_token
|
||||
from lib.auth import validate_token
|
||||
|
||||
token_param = None
|
||||
|
||||
@@ -392,16 +392,11 @@ async def _handle_ws(request: web.Request) -> web.Response:
|
||||
{"ok": False, "error": "authentication required"}, status=401
|
||||
)
|
||||
|
||||
# Decode token to extract session_id from payload (browsers can't send
|
||||
# X-Session-Id header on WebSocket connections, only subprotocols)
|
||||
raw_payload = decode_token(token_param)
|
||||
if raw_payload is None:
|
||||
return web.json_response({"ok": False, "error": "unauthorized"}, status=401)
|
||||
|
||||
# Validate token. Session binding is skipped because browsers cannot send
|
||||
# custom headers on WebSocket connections (no X-Session-Id available).
|
||||
payload = validate_token(
|
||||
token_param,
|
||||
token_type="access",
|
||||
session_id=raw_payload.get("session_id"),
|
||||
)
|
||||
if payload is None:
|
||||
return web.json_response({"ok": False, "error": "unauthorized"}, status=401)
|
||||
|
||||
Reference in New Issue
Block a user