Aller au contenu principal
Version: 0.2.0-beta.1

Configurer l’authentification Bearer dans le serveur MCP

Avec la dernière spécification MCP, votre serveur MCP agit comme un Serveur de ressources qui valide les jetons d’accès pour les ressources protégées. MCP Auth propose différentes façons de configurer l’autorisation Bearer :

  • Mode JWT (JSON Web Token) : Une méthode d’autorisation intégrée qui vérifie les JWT avec des assertions de revendications.
  • Mode personnalisé : Vous permet d’implémenter votre propre logique d’autorisation.

Le middleware d’authentification Bearer nécessite désormais de spécifier à quelle ressource appartient l’endpoint, permettant ainsi une validation correcte du jeton par rapport aux serveurs d’autorisation configurés.

Configurer l’authentification Bearer en mode JWT

Si votre fournisseur OAuth / OIDC émet des JWT pour l’autorisation, vous pouvez utiliser le mode JWT intégré dans MCP Auth. Il vérifie la signature du JWT, l’expiration et d’autres revendications que vous spécifiez ; puis il renseigne les informations d’authentification dans le contexte de la requête pour un traitement ultérieur dans votre implémentation MCP.

Validation de la portée (Scope)

Voici un exemple de validation de portée basique :

from mcpauth import MCPAuth
from starlette.applications import Starlette
from starlette.middleware import Middleware
from starlette.routing import Mount
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("MyMCPServer")
mcp_auth = MCPAuth(
    # Initialisez avec la configuration de votre serveur d’authentification
)
bearer_auth = mcp_auth.bearer_auth_middleware("jwt", 
    resource="https://api.example.com",  # Spécifiez à quelle ressource appartient cet endpoint
    audience="https://api.example.com",  # Activez la validation de l’audience pour la sécurité
    required_scopes=["read", "write"] 
)

app = Starlette(
    routes=[Mount('/', app=mcp.sse_app(), middleware=[Middleware(bearer_auth)])]
)

Dans l’exemple ci-dessus, nous avons spécifié que le JWT nécessite les portées read et write. Si le JWT ne contient aucune de ces portées, la requête sera rejetée avec une erreur 403 Forbidden.

Validation de l’audience (RFC 8707)

Pour une validation sécurisée du jeton, vous devez toujours inclure la validation de l’audience en spécifiant le paramètre audience. Cela valide la revendication aud (audience) dans le JWT pour s’assurer que le jeton a été émis spécifiquement pour la ressource de votre serveur MCP.

Audience Validation

Le paramètre audience est requis par la spécification OAuth 2.0 pour une validation sécurisée du jeton. Cependant, il est actuellement optionnel afin de maintenir la compatibilité avec les serveurs d’autorisation qui ne prennent pas encore en charge les identifiants de ressource. Pour des raisons de sécurité, incluez toujours le paramètre audience lorsque cela est possible. Les versions futures rendront la validation de l’audience obligatoire pour se conformer pleinement à la spécification.

La valeur de l’audience doit généralement correspondre à votre identifiant de ressource :

bearer_auth = mcp_auth.bearer_auth_middleware(
    "jwt",
    resource="https://api.example.com",  # Spécifiez à quelle ressource appartient cet endpoint
    audience="https://api.example.com",  # Activez la validation de l’audience pour la sécurité
    required_scopes=["read", "write"]
)

Dans l’exemple ci-dessus, MCP Auth validera à la fois la revendication aud dans le JWT et les portées requises.

Fournir des options personnalisées à la vérification JWT

Vous pouvez également fournir des options personnalisées à la bibliothèque de vérification JWT sous-jacente :

Dans le SDK Python, nous utilisons PyJWT pour la vérification des JWT. Vous pouvez utiliser les options suivantes :

  • leeway : Autorise une certaine tolérance lors de la vérification de l’expiration du JWT (en secondes). La valeur par défaut est de 60 secondes.
bearer_auth = mcp_auth.bearer_auth_middleware(
    "jwt",
    resource="https://api.example.com",
    audience="https://api.example.com",
    required_scopes=["read", "write"],
    leeway=10,  # Réduisez le décalage d’horloge en autorisant 10 secondes de tolérance
)

Configurer l’authentification Bearer avec une vérification personnalisée

Si votre fournisseur OAuth / OIDC n’émet pas de JWT, ou si vous souhaitez implémenter votre propre logique d’autorisation, MCP Auth vous permet de créer une fonction de vérification personnalisée :

info

Puisque le middleware d’authentification Bearer vérifiera l’émetteur (iss), l’audience (aud) et les portées requises (scope) avec le résultat de la vérification fourni, il n’est pas nécessaire d’implémenter ces vérifications dans votre fonction de vérification personnalisée. Vous pouvez vous concentrer sur la vérification de la validité du jeton (par exemple, signature, expiration, etc.) et retourner l’objet d’informations d’authentification.

from mcpauth.exceptions import MCPAuthJwtVerificationException, MCPAuthJwtVerificationExceptionCode
from mcpauth.types import AuthInfo

async def custom_verification(token: str) -> AuthInfo:
    # Implémentez ici votre logique de vérification personnalisée
    info = await verify_token(token)
    if not info:
        raise MCPAuthJwtVerificationException(
            MCPAuthJwtVerificationExceptionCode.JWT_VERIFICATION_FAILED
        )
    return info  # Retournez l’objet d’informations d’authentification

bearer_auth = mcp_auth.bearer_auth_middleware(
    custom_verification,
    resource="https://api.example.com",
    audience="https://api.example.com",  # Activez la validation de l’audience pour la sécurité
    required_scopes=["read", "write"]
)

Appliquer l’authentification Bearer dans votre serveur MCP

Pour protéger votre serveur MCP avec l’authentification Bearer, vous devez appliquer le middleware Bearer auth à votre instance de serveur MCP.

bearer_auth = mcp_auth.bearer_auth_middleware("jwt", 
    resource="https://api.example.com",
    audience="https://api.example.com",  # Activez la validation de l’audience pour la sécurité
    required_scopes=["read", "write"]
)
app = Starlette(
    routes=[Mount('/', app=mcp.sse_app(), middleware=[Middleware(bearer_auth)])]
)

Cela garantira que toutes les requêtes entrantes sont authentifiées et autorisées selon la configuration Bearer auth, et que les informations d’authentification seront disponibles dans le contexte de la requête.

Vous pouvez ensuite accéder à ces informations dans votre implémentation du serveur MCP :

@mcp.tool()
async def whoami() -> dict:
    # `mcp_auth.auth_info` est l’objet de contexte pour la requête en cours
    auth_info = mcp_auth.auth_info
    print(f"Utilisateur authentifié : {auth_info.subject}")
    return {"subject": auth_info.subject}