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 :
- Python
- Node.js
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)])]
)
import express from 'express';
import { MCPAuth } from 'mcp-auth';
const app = express();
const mcpAuth = new MCPAuth({
/* ... */
});
const bearerAuth = mcpAuth.bearerAuth('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é
requiredScopes: ['read', 'write']
});
app.use('/mcp', bearerAuth, (req, res) => {
// Maintenant `req.auth` contient les infos d’authentification
console.log(req.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.
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 :
- Python
- Node.js
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"]
)
const bearerAuth = mcpAuth.bearerAuth('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é
requiredScopes: ['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 :
- Python
- Node.js
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
)
Dans le SDK Node.js, nous utilisons la bibliothèque jose pour la vérification des JWT. Vous pouvez fournir les options suivantes :
jwtVerify
: Options pour le processus de vérification JWT (fonctionjwtVerify
dejose
).remoteJwtSet
: Options pour la récupération du jeu de JWT distant (fonctioncreateRemoteJWKSet
dejose
).
const bearerAuth = mcpAuth.bearerAuth('jwt', {
resource: 'https://api.example.com',
audience: 'https://api.example.com',
requiredScopes: ['read', 'write'],
jwtVerify: {
clockTolerance: 60, // Autorise un décalage d’horloge de 60 secondes
},
remoteJwtSet: {
timeoutDuration: 10 * 1000, // Délai d’attente de 10 secondes pour la récupération du JWT distant
},
});
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 :
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.
- Python
- Node.js
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"]
)
const bearerAuth = mcpAuth.bearerAuth(
async (token) => {
// Implémentez ici votre logique de vérification personnalisée
const info = await verifyToken(token);
if (!info) {
throw new MCPAuthJwtVerificationError('jwt_verification_failed');
}
return info; // Retournez l’objet d’informations d’authentification
},
{
resource: 'https://api.example.com',
audience: 'https://api.example.com', // Activez la validation de l’audience pour la sécurité
requiredScopes: ['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.
- Python
- Node.js
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)])]
)
const app = express();
app.use(mcpAuth.bearerAuth('jwt', {
resource: 'https://api.example.com',
audience: 'https://api.example.com', // Activez la validation de l’audience pour la sécurité
requiredScopes: ['read', 'write']
}));
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 :
- Python
- Node.js
@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}
// `authInfo` sera transmis depuis l’objet `req.auth`
server.tool('whoami', ({ authInfo }) => {
console.log(`Utilisateur authentifié : ${authInfo.subject}`);
return { subject: authInfo.subject };
});