Aller au contenu principal

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 avec le 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 et de l’audience

Validation de l’audience (Audience Validation)

Le paramètre audience est obligatoire selon 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é, veuillez toujours inclure 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.

Toujours valider les portées

Dans OAuth 2.0, les portées (Scopes) sont le principal mécanisme de contrôle des permissions. Un jeton valide avec la bonne audience ne garantit PAS que l'utilisateur a la permission d'effectuer une action — les serveurs d'autorisation peuvent émettre des jetons avec une portée vide ou limitée.

Utilisez toujours requiredScopes pour vous assurer que le jeton contient les permissions nécessaires pour chaque opération. Ne supposez jamais qu'un jeton valide implique un accès complet.

Voici un exemple de validation basique de la portée et de l’audience :

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 :

  • Le paramètre audience valide la revendication aud dans le JWT pour s’assurer que le jeton a été émis spécifiquement pour la ressource de votre serveur MCP. La valeur de l’audience doit généralement correspondre à votre identifiant de ressource.
  • Le paramètre requiredScopes indique que le JWT doit contenir les portées read et write. Si le jeton ne contient pas toutes ces portées, une erreur sera levée.

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 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 (fonction jwtVerify de jose).
  • remoteJwtSet : Options pour la récupération du jeu JWT distant (fonction createRemoteJWKSet de jose).
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 jeu 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 :

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 fournie, 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.

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.

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 les paramètres Bearer auth configurés, 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 :

// `authInfo` sera transmis depuis l’objet `req.auth`
server.registerTool(
  'whoami',
  {
    description: 'Retourne les informations de l’utilisateur actuel',
    inputSchema: {},
  },
  ({ authInfo }) => {
    console.log(`Utilisateur authentifié : ${authInfo.subject}`);
    return { subject: authInfo.subject };
  }
);