Zum Hauptinhalt springen

Bearer-Authentifizierung im MCP-Server konfigurieren

Mit der neuesten MCP-Spezifikation agiert dein MCP-Server als Ressourcenserver, der Zugangstokens für geschützte Ressourcen validiert. MCP Auth bietet verschiedene Möglichkeiten, die Bearer-Autorisierung zu konfigurieren:

  • JWT (JSON Web Token)-Modus: Eine integrierte Autorisierungsmethode, die JWTs mit Anspruchsüberprüfungen verifiziert.
  • Benutzerdefinierter Modus: Ermöglicht es dir, deine eigene Autorisierungslogik zu implementieren.

Das Bearer-Auth-Middleware erfordert jetzt die Angabe, zu welcher Ressource der Endpunkt gehört, um eine ordnungsgemäße Token-Validierung gegenüber den konfigurierten Autorisierungsservern zu ermöglichen.

Bearer-Authentifizierung mit JWT-Modus konfigurieren

Wenn dein OAuth / OIDC-Anbieter JWTs zur Autorisierung ausstellt, kannst du den integrierten JWT-Modus in MCP Auth verwenden. Er überprüft die JWT-Signatur, das Ablaufdatum und andere von dir angegebene Ansprüche; anschließend werden die Authentifizierungsinformationen im Request-Kontext für die weitere Verarbeitung in deiner MCP-Implementierung bereitgestellt.

Berechtigungs- und Zielgruppenvalidierung

Zielgruppenvalidierung (Audience Validation)

Der audience-Parameter ist gemäß der OAuth 2.0-Spezifikation für eine sichere Token-Validierung erforderlich. Er ist jedoch derzeit optional, um die Kompatibilität mit Autorisierungsservern zu gewährleisten, die Ressourcenindikatoren noch nicht unterstützen. Aus Sicherheitsgründen solltest du den audience-Parameter immer angeben, wenn möglich. Zukünftige Versionen werden die Zielgruppenvalidierung verpflichtend machen, um die Spezifikation vollständig zu erfüllen.

Immer Berechtigungen (Scopes) validieren

In OAuth 2.0 sind Berechtigungen (Scopes) der primäre Mechanismus zur Berechtigungssteuerung. Ein gültiges Token mit der richtigen audience garantiert NICHT, dass der Benutzer die Berechtigung hat, eine Aktion auszuführen — Autorisierungsserver können Tokens mit leerer oder eingeschränkter Berechtigung ausstellen.

Verwende immer requiredScopes, um sicherzustellen, dass das Token die notwendigen Berechtigungen für jede Operation enthält. Gehe niemals davon aus, dass ein gültiges Token vollen Zugriff impliziert.

Hier ist ein Beispiel für die grundlegende Berechtigungs- und Zielgruppenvalidierung:

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', // Gib an, zu welcher Ressource dieser Endpunkt gehört
  audience: 'https://api.example.com', // Aktiviere die Zielgruppenvalidierung für Sicherheit
  requiredScopes: ['read', 'write'],
});

app.use('/mcp', bearerAuth, (req, res) => {
  // Jetzt enthält `req.auth` die Authentifizierungsinformationen
  console.log(req.auth);
});

Im obigen Beispiel gilt:

  • Der audience-Parameter validiert den aud-Anspruch im JWT, um sicherzustellen, dass das Token speziell für deine MCP-Server-Ressource ausgestellt wurde. Der Audience-Wert sollte in der Regel mit deinem Ressourcenindikator übereinstimmen.
  • Der requiredScopes-Parameter gibt an, dass das JWT die Berechtigungen read und write enthalten muss. Wenn das Token nicht alle diese Berechtigungen enthält, wird ein Fehler ausgelöst.

Benutzerdefinierte Optionen für die JWT-Überprüfung angeben

Du kannst auch benutzerdefinierte Optionen für die zugrunde liegende JWT-Überprüfungsbibliothek angeben. Im Node.js SDK verwenden wir die jose-Bibliothek für die JWT-Überprüfung. Du kannst folgende Optionen angeben:

  • jwtVerify: Optionen für den JWT-Überprüfungsprozess (jwtVerify-Funktion aus jose).
  • remoteJwtSet: Optionen zum Abrufen des Remote-JWT-Sets (createRemoteJWKSet-Funktion aus jose).
const bearerAuth = mcpAuth.bearerAuth('jwt', {
  resource: 'https://api.example.com',
  audience: 'https://api.example.com',
  requiredScopes: ['read', 'write'],
  jwtVerify: {
    clockTolerance: 60, // Erlaube eine Zeitabweichung von 60 Sekunden
  },
  remoteJwtSet: {
    timeoutDuration: 10 * 1000, // 10 Sekunden Timeout für das Abrufen des Remote-JWT-Sets
  },
});

Bearer-Authentifizierung mit benutzerdefinierter Überprüfung konfigurieren

Wenn dein OAuth / OIDC-Anbieter keine JWTs ausstellt oder du deine eigene Autorisierungslogik implementieren möchtest, ermöglicht dir MCP Auth die Erstellung einer benutzerdefinierten Überprüfungsfunktion:

info

Da das Bearer-Auth-Middleware die Überprüfung von Aussteller (iss), Zielgruppe (aud) und erforderlichen Berechtigungen (scope) mit dem angegebenen Überprüfungsergebnis übernimmt, musst du diese Prüfungen nicht in deiner benutzerdefinierten Überprüfungsfunktion implementieren. Du kannst dich darauf konzentrieren, die Token-Gültigkeit zu überprüfen (z. B. Signatur, Ablauf usw.) und das Auth-Info-Objekt zurückzugeben.

const bearerAuth = mcpAuth.bearerAuth(
  async (token) => {
    // Implementiere hier deine benutzerdefinierte Überprüfungslogik
    const info = await verifyToken(token);
    if (!info) {
      throw new MCPAuthJwtVerificationError('jwt_verification_failed');
    }
    return info; // Gib das Auth-Info-Objekt zurück
  },
  {
    resource: 'https://api.example.com',
    audience: 'https://api.example.com', // Aktiviere die Zielgruppenvalidierung für Sicherheit
    requiredScopes: ['read', 'write']
  }
);

Bearer-Authentifizierung in deinem MCP-Server anwenden

Um deinen MCP-Server mit Bearer-Authentifizierung zu schützen, musst du das Bearer-Auth-Middleware auf deine MCP-Server-Instanz anwenden.

const app = express();
app.use(mcpAuth.bearerAuth('jwt', {
  resource: 'https://api.example.com',
  audience: 'https://api.example.com', // Aktiviere die Zielgruppenvalidierung für Sicherheit
  requiredScopes: ['read', 'write']
}));

Dadurch wird sichergestellt, dass alle eingehenden Anfragen gemäß den konfigurierten Bearer-Auth-Einstellungen authentifiziert und autorisiert werden und die Authentifizierungsinformationen im Request-Kontext verfügbar sind.

Du kannst die Informationen dann in deiner MCP-Server-Implementierung abrufen:

// `authInfo` wird aus dem `req.auth`-Objekt übernommen
server.registerTool(
  'whoami',
  {
    description: 'Gibt die aktuellen Benutzerinformationen zurück',
    inputSchema: {},
  },
  ({ authInfo }) => {
    console.log(`Authentifizierter Benutzer: ${authInfo.subject}`);
    return { subject: authInfo.subject };
  }
);