Saltar al contenido principal

Configura la autenticación Bearer en el servidor MCP

Con la última especificación de MCP, tu servidor MCP actúa como un Servidor de Recursos que valida los tokens de acceso para los recursos protegidos. MCP Auth proporciona varias formas de configurar la autorización Bearer:

  • Modo JWT (JSON Web Token): Un método de autorización incorporado que verifica JWTs con aserciones de reclamos.
  • Modo personalizado: Te permite implementar tu propia lógica de autorización.

El middleware de autenticación Bearer ahora requiere especificar a qué recurso pertenece el endpoint, permitiendo una validación adecuada del token contra los servidores de autorización configurados.

Configura la autenticación Bearer con el modo JWT

Si tu proveedor OAuth / OIDC emite JWTs para la autorización, puedes usar el modo JWT incorporado en MCP Auth. Verifica la firma del JWT, la expiración y otros reclamos que especifiques; luego, rellena la información de autenticación en el contexto de la solicitud para su posterior procesamiento en tu implementación MCP.

Validación de alcance y audiencia

Validación de audiencia

El parámetro audience es requerido por la especificación OAuth 2.0 para una validación segura del token. Sin embargo, actualmente es opcional para mantener la compatibilidad con servidores de autorización que aún no admiten identificadores de recursos. Por razones de seguridad, por favor incluye siempre el parámetro de audiencia cuando sea posible. Las versiones futuras harán que la validación de audiencia sea obligatoria para cumplir completamente con la especificación.

Siempre valida los alcances (Scopes)

En OAuth 2.0, los alcances (scopes) son el mecanismo principal para el control de permisos. Un token válido con la audience correcta NO garantiza que el usuario tenga permiso para realizar una acción: los servidores de autorización pueden emitir tokens con un alcance vacío o limitado.

Utiliza siempre requiredScopes para asegurar que el token contiene los permisos necesarios para cada operación. Nunca asumas que un token válido implica acceso completo.

Aquí tienes un ejemplo de la validación básica de alcance y audiencia:

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', // Especifica a qué recurso pertenece este endpoint
  audience: 'https://api.example.com', // Habilita la validación de audiencia por seguridad
  requiredScopes: ['read', 'write'],
});

app.use('/mcp', bearerAuth, (req, res) => {
  // Ahora `req.auth` contiene la información de autenticación
  console.log(req.auth);
});

En el ejemplo anterior:

  • El parámetro audience valida el reclamo aud en el JWT para asegurar que el token fue emitido específicamente para el recurso de tu servidor MCP. El valor de audiencia normalmente debe coincidir con tu identificador de recurso.
  • El parámetro requiredScopes especifica que el JWT requiere los alcances read y write. Si el token no contiene todos estos alcances, se lanzará un error.

Proporciona opciones personalizadas a la verificación JWT

También puedes proporcionar opciones personalizadas a la biblioteca de verificación JWT subyacente. En el SDK de Node.js, usamos la biblioteca jose para la verificación de JWT. Puedes proporcionar las siguientes opciones:

  • jwtVerify: Opciones para el proceso de verificación JWT (función jwtVerify de jose).
  • remoteJwtSet: Opciones para obtener el conjunto JWT remoto (función createRemoteJWKSet de jose).
const bearerAuth = mcpAuth.bearerAuth('jwt', {
  resource: 'https://api.example.com',
  audience: 'https://api.example.com',
  requiredScopes: ['read', 'write'],
  jwtVerify: {
    clockTolerance: 60, // Permite una desviación de reloj de 60 segundos
  },
  remoteJwtSet: {
    timeoutDuration: 10 * 1000, // 10 segundos de tiempo de espera para obtener el conjunto JWT remoto
  },
});

Configura la autenticación Bearer con verificación personalizada

Si tu proveedor OAuth / OIDC no emite JWTs, o deseas implementar tu propia lógica de autorización, MCP Auth te permite crear una función de verificación personalizada:

info

Dado que el middleware de autenticación Bearer comprobará el emisor (iss), la audiencia (aud) y los alcances requeridos (scope) con el resultado de la verificación proporcionado, no es necesario implementar estas comprobaciones en tu función de verificación personalizada. Puedes centrarte en verificar la validez del token (por ejemplo, firma, expiración, etc.) y devolver el objeto de información de autenticación.

const bearerAuth = mcpAuth.bearerAuth(
  async (token) => {
    // Implementa aquí tu lógica de verificación personalizada
    const info = await verifyToken(token);
    if (!info) {
      throw new MCPAuthJwtVerificationError('jwt_verification_failed');
    }
    return info; // Devuelve el objeto de información de autenticación
  },
  {
    resource: 'https://api.example.com',
    audience: 'https://api.example.com', // Habilita la validación de audiencia por seguridad
    requiredScopes: ['read', 'write']
  }
);

Aplica la autenticación Bearer en tu servidor MCP

Para proteger tu servidor MCP con autenticación Bearer, necesitas aplicar el middleware de autenticación Bearer a tu instancia del servidor MCP.

const app = express();
app.use(mcpAuth.bearerAuth('jwt', {
  resource: 'https://api.example.com',
  audience: 'https://api.example.com', // Habilita la validación de audiencia por seguridad
  requiredScopes: ['read', 'write']
}));

Esto asegurará que todas las solicitudes entrantes estén autenticadas y autorizadas según la configuración de autenticación Bearer, y la información de autenticación estará disponible en el contexto de la solicitud.

Luego puedes acceder a la información en tu implementación del servidor MCP:

// `authInfo` se obtendrá del objeto `req.auth`
server.registerTool(
  'whoami',
  {
    description: 'Devuelve la información del usuario actual',
    inputSchema: {},
  },
  ({ authInfo }) => {
    console.log(`Usuario autenticado: ${authInfo.subject}`);
    return { subject: authInfo.subject };
  }
);