Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 10 additions & 17 deletions superset/mcp_service/jwt_verifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,7 @@
from typing import Any, cast

import httpx
from authlib.jose.errors import (
BadSignatureError,
DecodeError,
ExpiredTokenError,
JoseError,
)
from authlib.jose.errors import JoseError
from fastmcp.server.auth.auth import AccessToken
from fastmcp.server.auth.providers.jwt import JWTVerifier
from mcp.server.auth.middleware.auth_context import AuthContextMiddleware
Expand Down Expand Up @@ -491,7 +486,7 @@ async def load_access_token(self, token: str) -> AccessToken | None: # noqa: C9
# Step 1: Decode header and check algorithm
try:
header = self._decode_token_header(token)
except (ValueError, DecodeError) as e:
except ValueError as e:
reason = "Malformed token header"
_jwt_failure_reason.set(reason)
logger.debug("Malformed token header: %s", e)
Expand Down Expand Up @@ -566,18 +561,16 @@ async def load_access_token(self, token: str) -> AccessToken | None: # noqa: C9
# Step 3: Decode and verify signature
try:
claims = self.jwt.decode(token, verification_key)
except BadSignatureError:
reason = "Signature verification failed"
_jwt_failure_reason.set(reason)
return None
except ExpiredTokenError:
reason = "Token has expired (detected during decode)"
_jwt_failure_reason.set(reason)
return None
except JoseError as e:
reason = "Token decode failed"
error_code = getattr(e, "error", None)
if error_code == "bad_signature":
reason = "Signature verification failed"
elif error_code == "expired_token":
reason = "Token has expired (detected during decode)"
else:
reason = "Token decode failed"
logger.debug("Token decode failed: %s", e)
_jwt_failure_reason.set(reason)
logger.debug("Token decode failed: %s", e)
return None

# Extract client ID for logging
Expand Down
3 changes: 1 addition & 2 deletions superset/mcp_service/mcp_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import secrets
from typing import Any, Dict, Optional, Sequence

from authlib.jose.errors import JoseError
from fastmcp.server.auth.providers.jwt import JWTVerifier
from flask import Flask

Expand Down Expand Up @@ -379,7 +378,7 @@ def create_default_mcp_auth_factory(app: Flask) -> Optional[Any]:
public_key=public_key,
secret=secret,
)
except (ValueError, JoseError):
except Exception:
# Do not log the exception — it may contain secrets (e.g., key material)
logger.error("Failed to create MCP JWT verifier")
if not api_key_enabled:
Expand Down
Loading