content: import base64
  import binascii
  import hmac
  import time
  from typing import Any
  from urllib.parse import unquote
  
  from starlette.requests import Request
  
  from mcp.server.auth.provider import OAuthAuthorizationServerProvider
  from mcp.shared.auth import OAuthClientInformationFull
  
  
  class AuthenticationError(Exception):
      def __init__(self, message: str):
          self.message = message  # pragma: no cover
  
  
  class ClientAuthenticator:
      """
      ClientAuthenticator is a callable which validates requests from a client
      application, used to verify /token calls.
      If, during registration, the client requested to be issued a secret, the
      authenticator asserts that /token calls must be authenticated with
      that same token.
      NOTE: clients can opt for no authentication during registration, in which case this
      logic is skipped.
      """
  
      def __init__(self, provider: OAuthAuthorizationServerProvider[Any, Any, Any]):
          """
          Initialize the dependency.
  
          Args:
              provider: Provider to look up client information
          """
          self.provider = provider
  
      async def authenticate_request(self, request: Request) -> OAuthClientInformationFull:
          """
          Authenticate a client from an HTTP request.
  
          Extracts client credentials from the appropriate location based on the
          client's registered authentication method and validates them.
  
          Args:
              request: The HTTP request containing client credentials
  
          Returns:
              The authenticated client information
  
          Raises:
              AuthenticationError: If authentication fails
          """
          form_data = await request.form()
          client_id = form_data.get("client_id")
          if not client_id:
              raise AuthenticationError("Missing client_id")
  
          client = await self.provider.get_client(str(client_id))
          if not client:
              raise AuthenticationError("Invalid client_id")  # pragma: no cover
  
          request_client_secret: str | None = None
          auth_header = request.headers.get("Authorization", "")
  
          if client.token_endpoint_auth_method == "client_secret_basic":
              if not auth_header.startswith("Basic "):
                  raise AuthenticationError("Missing or invalid Basic authentication in Authorization header")
  
              try:
                  encoded_credentials = auth_header[6:]  # Remove "Basic " prefix
                  decoded = base64.b64decode(encoded_credentials).decode("utf-8")
                  if ":" not in decoded:
                      raise ValueError("Invalid Basic auth format")
                  basic_client_id, request_client_secret = decoded.split(":", 1)
  
                  # URL-decode both parts per RFC 6749 Section 2.3.1
                  basic_client_id = unquote(basic_client_id)
                  request_client_secret = unquote(request_client_secret)
  
                  if basic_client_id != client_id:
                      raise AuthenticationError("Client ID mismatch in Basic auth")
              except (ValueError, UnicodeDecodeError, binascii.Error):
                  raise AuthenticationError("Invalid Basic authentication header")
  
          elif client.token_endpoint_auth_method == "client_secret_post":
              raw_form_data = form_data.get("client_secret")
              # form_data.get() can return a UploadFile or None, so we need to check if it's a string
              if isinstance(raw_form_data, str):
                  request_client_secret = str(raw_form_data)
  
          elif client.token_endpoint_auth_method == "none":
              request_client_secret = None
          else:
              raise AuthenticationError(  # pragma: no cover
                  f"Unsupported auth method: {client.token_endpoint_auth_method}"
              )
  
          # If client from the store expects a secret, validate that the request provides
          # that secret
          if client.client_secret:  # pragma: no branch
              if not request_client_secret:
                  raise AuthenticationError("Client secret is required")  # pragma: no cover
  
              # hmac.compare_digest requires that both arguments are either bytes or a `str` containing
              # only ASCII characters. Since we do not control `request_client_secret`, we encode both
              # arguments to bytes.
              if not hmac.compare_digest(client.client_secret.encode(), request_client_secret.encode()):
                  raise AuthenticationError("Invalid client_secret")  # pragma: no cover
  
              if client.client_secret_expires_at and client.client_secret_expires_at < int(time.time()):
                  raise AuthenticationError("Client secret has expired")  # pragma: no cover
  
          return client
  