diff --git a/superset/mcp_service/jwt_verifier.py b/superset/mcp_service/jwt_verifier.py index 605a2577717b..ef460d6ffebd 100644 --- a/superset/mcp_service/jwt_verifier.py +++ b/superset/mcp_service/jwt_verifier.py @@ -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 @@ -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) @@ -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 diff --git a/superset/mcp_service/mcp_config.py b/superset/mcp_service/mcp_config.py index 33a4e45c142b..150cd48a395b 100644 --- a/superset/mcp_service/mcp_config.py +++ b/superset/mcp_service/mcp_config.py @@ -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 @@ -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: