Inicio / Artículos / Notas prácticas: Receta de Spring AI: Proteger un servidor MCP con OAuth

Notas prácticas: Receta de Spring AI: Proteger un servidor MCP con OAuth

Guía paso a paso operativa de las notas prácticas: Receta de Spring AI: Proteger un servidor MCP con OAuth: contratos, verificaciones y espacios para código listo para uso destinados a los equipos que implementan este patrón.

1607 palabras

Las notas siguientes reconstruyen un camino práctico para abordar “Spring AI Recipe: Securing an MCP Server with OAuth”. Se da énfasis en los contratos, las verificaciones y los marcadores de posición para código reutilizable, en lugar de en un enfoque motivacional. Al trabajar en la etapa de descripción general, anote primero el contrato: las entradas requeridas, la señal de éxito y qué ocurre en caso de un fallo parcial. Esa lista de verificación garantiza que los cambios posteriores en el código sean transparentes. Mantenga la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de credenciales secretas y las banderas de funcionalidad deben estar en un lugar donde los administradores puedan auditarlos sin tener que leer todo el código.

Creación del servidor de autorización

La etapa de creación del servidor de autorización funciona mejor cuando se trata como una superficie medible. Capture un registro ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance. Documente tanto el camino óptimo como el de recuperación. Las reintentos, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son mejoras posteriores. Exponga herramientas con esquemas limitados y etiquetas explícitas de efectos secundarios. Los hosts necesitan saber qué llamadas modifican el estado antes de aprobarlas automáticamente.

implementation 'org.springaicommunity:mcp-authorization-server:0.1.14'
@Configuration
@EnableWebSecurity
public class SecurityConfig {

  @Bean
  SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    return http
        .authorizeHttpRequests(auth ->
            auth.anyRequest().authenticated())
        .formLogin(withDefaults())
        .with(
            McpAuthorizationServerConfigurer.mcpAuthorizationServer(),
            withDefaults())
        .build();
  }

}
spring:
  application:
    name: recipes-authorization-server
  security:
    oauth2:
      authorizationserver:
        client:
          default-client:
            token:
              access-token-time-to-live: 1h
            registration:
              client-id: "myclient"
              client-secret: "{noop}mysecret"
              client-authentication-methods:
                - "client_secret_basic"
              authorization-grant-types:
                - "authorization_code"
              redirect-uris:
                - "http://localhost:6274/oauth/callback"
                - "http://127.0.0.1:6274/oauth/callback"
              scopes:
                - general-access
                - meteorology
                - administration
    user:
      name: craig
      password: letmein

server:
  port: 9999

Protegiendo el servidor MCP

La etapa de asegurar el servidor MCP funciona mejor cuando se trata como una superficie medible. Capture un registro de éxito ejemplar, un caso de fallo y la nota de reversión antes de ampliar el alcance. Prefiera unidades pequeñas y verificables en lugar de scripts extensos. Cuando falla un paso, el fallo debe apuntar a una única responsabilidad y no a un proceso complicado. Exponga herramientas con esquemas limitados y etiquetas explícitas sobre efectos secundarios. Los hosts necesitan saber qué llamadas modifican el estado antes de aprobarlas automáticamente.

implementation 'org.springaicommunity:mcp-server-security:0.1.14'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:9999
@Configuration
@EnableWebSecurity
class McpSecurityConfig {

  @Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}")
  private String issuerUrl;

  @Bean
  SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    return http
        .authorizeHttpRequests(auth ->
            auth.anyRequest().authenticated())
        .with(
            McpServerOAuth2Configurer.mcpServerOAuth2(),
            (mcpAuthorization) -> {
              mcpAuthorization.authorizationServer(issuerUrl);
            }
        )
        .build();
  }

}

Pruebas del servidor MCP

La etapa de Prueba del servidor MCP funciona mejor cuando se trata como una superficie medible. Capture un registro ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance. Trate esta etapa como un contrato entre las entradas y las salidas validadas. Asigne nombres a los artefactos, defina verificaciones de éxito y rechace completaciones parciales silenciosas. Exponga herramientas con esquemas limitados y etiquetas explícitas de efectos secundarios. Los hosts necesitan saber qué llamadas modifican el estado antes de aprobarlas automáticamente. La etapa de Prueba del servidor MCP funciona mejor cuando se trata como una superficie medible. Capture un registro ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance. Mantenga la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de secretos y las banderas de funcionalidad deben estar en un lugar donde los operadores puedan auditarlos sin tener que leer todo el sistema.

Proteger las herramientas individuales

En la fase de herramientas individuales seguras, defina las entradas, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Documente tanto la ruta óptima como la ruta de recuperación. Las intentonas, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son mejoras posteriores. Autentique en la pasarela y vuelva a autorizarlo en el plano de datos. Un token portador por sí solo no constituye un límite entre tenencias.

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
class SecurityConfig {

  @Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}")
  private String issuerUrl;

  @Bean
  SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    return http
        .authorizeHttpRequests(auth -> {
          auth.requestMatchers("/mcp").permitAll();
          auth.anyRequest().authenticated();
        })
        .with(
            McpServerOAuth2Configurer.mcpServerOAuth2(),
            (mcpAuthorization) -> {
              mcpAuthorization.authorizationServer(issuerUrl);
            }
        )
        .build();
  }

}
@PreAuthorize("hasAuthority('SCOPE_meteorology')")
@McpTool(
    name = "get-weather-for-zipcode",
    description = "Gets the weather for a given zipcode",
    annotations = @McpTool.McpAnnotations(
        openWorldHint = false,
        destructiveHint = false,
        idempotentHint = true))
Weather getWeatherForZipcode(
    @McpToolParam(description = "The zipcode to get weather for")
    String zipcode) {
  var context = SecurityContextHolder.getContext();
  var username = context.getAuthentication().getName();
  return new Weather(
      zipcode,
      "Raining cats and dogs",
      78.0f,
      username);
}

Lista de verificación operativa

En la fase de la lista de verificación operativa, defina las entradas, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto.

Registre los tiempos de ejecución y el costo de los tokens o consultas junto con los resultados funcionales. Ver la información sobre costos desde el principio evita facturas inesperadas cuando el entorno pasa de la versión de demostración a entornos compartidos.

Autentíquese en la pasarela y vuelva a autorizarlo en el plano de datos. Un token portador por sí solo no constituye un límite entre tenencias.

Escriba un manual breve: cómo rotar las claves, cómo vaciar la cola de tareas y cómo revertir la última operación de ingreso de datos.

Mantenga la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de secretos y las banderas de funcionalidad deben estar en un único lugar que los operadores puedan auditar sin tener que leer todo el sistema.

Autentíquese en la pasarela y vuelva a autorizarlo en el plano de datos. Un token portador por sí solo no constituye un límite entre tenencias.

Antes de promocionar la solución, congele las versiones, capture una transcripción de referencia para el camino crítico y confirme los pasos de reversión. Los entornos compartidos requieren límites de velocidad, verificaciones de tenencia y un responsable claro para la rotación de credenciales secretas. Prefiera una fiabilidad sencilla a demostraciones ingeniosas pero puntuales.

Nota para el lote 01496ca9e17e: mantenga las claves del proveedor fuera del repositorio, establezca un límite máximo para tokens por sesión y almacene las transcripciones junto a los archivos de prueba para que los cambios posteriores en el modelo sigan siendo comparables.

Para la nota de fortalecimiento en la etapa 0, defina las entradas, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Trate esta etapa como un contrato entre las entradas y los resultados validados. Asigne nombres a los artefactos, defina verificaciones de éxito y rechace completaciones parciales silenciosas.

Detalle de refuerzo 0/819: mida el tiempo de ejecución, la clase de error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.

Al trabajar en la primera etapa de la nota de refuerzo, anote primero el contrato: las entradas requeridas, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código. Guarde la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de secretos y las banderas de funcionalidad deben estar en un lugar que los operadores puedan auditar sin tener que leer todo el grafo.

Detalle de refuerzo 1/819: mida el tiempo de ejecución, la clase de error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.

La fase 2 de las notas de fortalecimiento funciona mejor cuando se trata como una superficie medible. Capture una transcripción ejemplar, un caso de fallo y la nota de reversión antes de ampliar el alcance. Prefiera unidades pequeñas y verificables en lugar de scripts extensos. Cuando un paso falla, el fallo debe apuntar a una única responsabilidad y no a un proceso complicado.

Detalle de fortalecimiento 2/819: mida el tiempo de ejecución, la clase del error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.

Para la fase 3 de las notas de fortalecimiento, defina los insumos, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Registre los tiempos de ejecución y el costo en tokens o consultas junto con los resultados funcionales. La visibilidad temprana de los costos evita facturas inesperadas cuando el proceso pasa de entornos de demostración a entornos compartidos.

Detalle de fortalecimiento 3/819: mida el tiempo de ejecución, la clase del error y el gasto en tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en observaciones anecdóticas.

Al trabajar en la fase 4 de las notas de fortalecimiento, anote primero el contrato: los datos requeridos, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código.

Documente tanto el camino óptimo como el de recuperación. Las reintentos, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son mejoras posteriores.

El detalle de fortalecimiento 4/819: mida el tiempo de ejecución, la clase del error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de anécdotas.

La fase 5 de las notas de fortalecimiento funciona mejor cuando se trata como una superficie medible. Capture una transcripción ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance. Trate esta fase como un contrato entre los datos de entrada y los resultados validados. Asigne nombres a los artefactos, defina las verificaciones de éxito y rechace las completaciones parciales silenciosas.

Detalle de fortalecimiento 5/819: mida el tiempo de ejecución, la clase de error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.

Para la fase 6 de la nota de fortalecimiento, defina las entradas, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Mantenga la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de secretos y las banderas de funcionalidad deben estar en un lugar que los operadores puedan auditar sin tener que leer todo el sistema.

Detalle de fortalecimiento 6/819: mida el tiempo de ejecución, la clase de error y el consumo de tokens para esta nota, y luego decida si mantener el cambio basándose en un conjunto fijo de preguntas en lugar de en anécdotas.

Lecturas relacionadas

  • Audité 300 paquetes npm relacionados con MCP. Mi escáner no podía inspeccionar el entorno en ejecución — Guía paso a paso sobre cómo auditar 300 paquetes npm relacionados con MCP cuando el escáner no permite inspeccionar el entorno en ejecución: contratos, verificaciones y espacios para código adicional para los equipos que utilizan este patrón.