1. 概述注意此模块仍处于开发阶段文档和 API 可能在后续版本中发生变更。Spring AI MCP Security模块为Spring AI的模型上下文协议MCP实现提供了全面的OAuth 2.0和API Key安全支持。该社区驱动的项目使开发者能够使用行业标准的认证与授权机制来保护MCP服务端和客户端。此模块属于spring-ai-community/mcp-security项目目前仅兼容Spring AI 1.1.x分支。它是社区驱动项目尚未获得Spring AI或MCP项目的官方背书。三大核心组件组件用途MCP Server Security为Spring AIMCP服务端提供OAuth 2.0资源服务器和API Key认证MCP Client Security为Spring AIMCP客户端提供OAuth 2.0客户端支持MCP Authorization Server基于Spring Authorization Server增强针对MCP场景定制核心能力使用OAuth 2.0和API Key保护MCP服务端为MCP客户端配置OAuth 2.0授权流程搭建专为MCP工作流设计的授权服务器实现对MCP工具和资源的细粒度访问控制2. MCP 服务端安全为Spring AIMCP服务端提供OAuth 2.0资源服务器能力同时提供基础的API Key认证支持。注意此模块仅兼容Spring WebMVC服务端。2.1 依赖dependenciesdependencygroupIdorg.springaicommunity/groupIdartifactIdmcp-server-security/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-security/artifactId/dependency!-- 可选OAuth2 支持 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-oauth2-resource-server/artifactId/dependency/dependencies2.2 OAuth 2.0 配置基础 OAuth 2.0 配置首先在application.properties中启用MCP服务端spring.ai.mcp.server.namemy-cool-mcp-server # 支持的协议STREAMABLE, STATELESS spring.ai.mcp.server.protocolSTREAMABLE然后使用Spring Security标准 API 结合MCP配置器进行安全配置ConfigurationEnableWebSecurityclassMcpServerConfiguration{Value(${spring.security.oauth2.resourceserver.jwt.issuer-uri})privateStringissuerUrl;BeanSecurityFilterChainsecurityFilterChain(HttpSecurityhttp)throwsException{returnhttp// 对 EVERY 请求强制要求 token 认证.authorizeHttpRequests(auth-auth.anyRequest().authenticated())// 在 MCP 服务端上配置 OAuth2.with(McpServerOAuth2Configurer.mcpServerOAuth2(),(mcpAuthorization)-{// 必填issuerURImcpAuthorization.authorizationServer(issuerUrl);// 可选强制校验 JWT 中的 aud 声明// 并非所有授权服务器都支持 resource indicators因此可能缺失// 默认值为 false// 参见 RFC 8707 Resource Indicators for OAuth 2.0mcpAuthorization.validateAudienceClaim(true);}).build();}}仅保护工具调用可以配置服务端仅对工具调用进行安全保护其他MCP操作如initialize、tools/list保持公开ConfigurationEnableWebSecurityEnableMethodSecurity// 启用注解驱动的安全classMcpServerConfiguration{Value(${spring.security.oauth2.resourceserver.jwt.issuer-uri})privateStringissuerUrl;BeanSecurityFilterChainsecurityFilterChain(HttpSecurityhttp)throwsException{returnhttp// 开放服务端上的所有请求.authorizeHttpRequests(auth-{auth.requestMatcher(/mcp).permitAll();auth.anyRequest().authenticated();})// 在 MCP 服务端上配置 OAuth2.with(McpResourceServerConfigurer.mcpServerOAuth2(),(mcpAuthorization)-{// 必填issuerURImcpAuthorization.authorizationServer(issuerUrl);}).build();}}然后使用PreAuthorize注解结合方法安全来保护工具调用ServicepublicclassMyToolsService{PreAuthorize(isAuthenticated())McpTool(namegreeter,description用你选择的语言向你问好)publicStringgreet(ToolParam(description问好的语言例english、french…)Stringlanguage){if(!StringUtils.hasText(language)){language;}returnswitch(language.toLowerCase()){caseenglish-Hello you!;casefrench-Salut toi!;default-我不懂 \%s\ 语言所以只能说 Hello.formatted(language);};}}也可以通过SecurityContextHolder在工具方法中直接访问当前认证信息McpTool(namegreeter,description用指定语言向用户称呼名字问好)PreAuthorize(isAuthenticated())publicStringgreet(ToolParam(description问好的语言例english、french…)Stringlanguage){if(!StringUtils.hasText(language)){language;}varauthenticationSecurityContextHolder.getContext().getAuthentication();varnameauthentication.getName();returnswitch(language.toLowerCase()){caseenglish-Hello, %s!.formatted(name);casefrench-Salut %s!.formatted(name);default-(我不懂 \%s\ 语言所以只能说 Hello %s).formatted(language,name);};}2.3 API Key 认证MCP Server Security模块也支持基于API Key的认证。你需要提供自己的ApiKeyEntityRepository实现来存储ApiKeyEntity对象。框架提供了InMemoryApiKeyEntityRepository示例实现和默认的ApiKeyEntityImpl注意InMemoryApiKeyEntityRepository使用bcrypt存储API Key计算开销较高不适合高并发生产环境。生产环境请实现自己的ApiKeyEntityRepository。ConfigurationEnableWebSecurityclassMcpServerConfiguration{BeanSecurityFilterChainsecurityFilterChain(HttpSecurityhttp)throwsException{returnhttp.authorizeHttpRequests(authz-authz.anyRequest().authenticated()).with(mcpServerApiKey(),(apiKey)-{// 必填API Key 的存储仓库apiKey.apiKeyRepository(apiKeyRepository());// 可选携带 API Key 的请求头名称// 例如此处API Key 将通过 CUSTOM-API-KEY: value 发送// 替代 .authenticationConverter(...)见下方//// apiKey.headerName(CUSTOM-API-KEY);// 可选自定义转换器将 HTTP 请求转为认证对象// 适用于 header 为 Authorization: Bearer value 的场景// 替代 .headerName(...)见上方//// apiKey.authenticationConverter(request - {// var key extractKey(request);// return ApiKeyAuthenticationToken.unauthenticated(key);// });}).build();}/** * 提供 {link ApiKeyEntity} 的存储仓库 */privateApiKeyEntityRepositoryApiKeyEntityImplapiKeyRepository(){varapiKeyApiKeyEntityImpl.builder().name(test api key).id(api01).secret(mycustomapikey).build();returnnewInMemoryApiKeyEntityRepository(List.of(apiKey));}}配置完成后可通过请求头X-API-key: api01.mycustomapikey调用MCP服务端。2.4 已知限制限制说明SSE不支持已弃用的SSE传输不受支持请使用Streamable HTTP或Stateless传输WebFlux不支持不支持基于WebFlux的服务端Opaque Token不支持请使用JWT3. MCP 客户端安全为Spring AIMCP客户端提供OAuth 2.0支持同时兼容基于HttpClient的客户端spring-ai-starter-mcp-client和基于WebClient的客户端spring-ai-starter-mcp-client-webflux。注意此模块仅支持McpSyncClient。3.1 依赖dependencygroupIdorg.springaicommunity/groupIdartifactIdmcp-client-security/artifactId/dependency3.2 授权流程三种OAuth 2.0授权流程可供选择流程适用场景授权码流程authorization_code用户级别权限所有MCP请求均在用户请求上下文中发起客户端凭证流程client_credentials机器对机器通信无人工参与混合流程Hybrid部分操作如initialize、tools/list无需用户在场即可执行但工具调用需要用户级别权限选择建议当使用Spring Boot属性配置MCP客户端时推荐使用混合流程因为工具发现是在启动时进行的此时并无用户在场。3.3 通用配置所有流程都需要在application.properties中激活Spring SecurityOAuth2客户端支持# 确保 MCP 客户端为同步模式spring.ai.mcp.client.typeSYNC# 授权码流程或混合流程spring.security.oauth2.client.registration.authserver.client-id客户端IDspring.security.oauth2.client.registration.authserver.client-secret客户端密钥spring.security.oauth2.client.registration.authserver.authorization-grant-typeauthorization_code spring.security.oauth2.client.registration.authserver.providerauthserver# 客户端凭证流程或混合流程spring.security.oauth2.client.registration.authserver-client-credentials.client-id客户端IDspring.security.oauth2.client.registration.authserver-client-credentials.client-secret客户端密钥spring.security.oauth2.client.registration.authserver-client-credentials.authorization-grant-typeclient_credentials spring.security.oauth2.client.registration.authserver-client-credentials.providerauthserver# 授权服务器配置spring.security.oauth2.client.provider.authserver.issuer-uri授权服务器的ISSUER URI然后创建配置类激活OAuth2客户端能力ConfigurationEnableWebSecurityclassSecurityConfiguration{BeanSecurityFilterChainsecurityFilterChain(HttpSecurityhttp)throwsException{returnhttp// 此示例中客户端应用自身端点无安全保护.authorizeHttpRequests(auth-auth.anyRequest().permitAll())// 开启 OAuth2 支持.oauth2Client(Customizer.withDefaults()).build();}}3.4 HttpClient 客户端使用spring-ai-starter-mcp-client时配置McpSyncHttpClientRequestCustomizerBeanConfigurationclassMcpConfiguration{BeanMcpSyncClientCustomizersyncClientCustomizer(){return(name,syncSpec)-syncSpec.transportContextProvider(newAuthenticationMcpTransportContextProvider());}BeanMcpSyncHttpClientRequestCustomizerrequestCustomizer(OAuth2AuthorizedClientManagerclientManager){// clientRegistration 名称 authserver 须与 application.properties 中一致returnnewOAuth2AuthorizationCodeSyncHttpRequestCustomizer(clientManager,authserver);}}可用的Customizer实现类对应流程OAuth2AuthorizationCodeSyncHttpRequestCustomizer授权码流程OAuth2ClientCredentialsSyncHttpRequestCustomizer客户端凭证流程OAuth2HybridSyncHttpRequestCustomizer混合流程3.5 WebClient 客户端使用spring-ai-starter-mcp-client-webflux时通过MCP ExchangeFilterFunction配置WebClient.BuilderConfigurationclassMcpConfiguration{BeanMcpSyncClientCustomizersyncClientCustomizer(){return(name,syncSpec)-syncSpec.transportContextProvider(newAuthenticationMcpTransportContextProvider());}BeanWebClient.BuildermcpWebClientBuilder(OAuth2AuthorizedClientManagerclientManager){// clientRegistration 名称 authserver 须与 application.properties 中一致returnWebClient.builder().filter(newMcpOAuth2AuthorizationCodeExchangeFilterFunction(clientManager,authserver));}}可用的Filter实现类对应流程McpOAuth2AuthorizationCodeExchangeFilterFunction授权码流程McpOAuth2ClientCredentialsExchangeFilterFunction客户端凭证流程McpOAuth2HybridExchangeFilterFunction混合流程3.6 绕过 Spring AI 自动配置Spring AI的自动配置会在启动时初始化MCP客户端这可能导致基于用户认证的场景出问题。以下提供两种绕过方案方案一禁用 Tool 自动配置发布一个空的ToolCallbackResolverBean 来禁用Spring AI的Tool自动配置ConfigurationpublicclassMcpConfiguration{BeanToolCallbackResolverresolver(){returnnewStaticToolCallbackResolver(List.of());}}方案二编程式客户端配置以编程方式配置MCP客户端替代Spring Boot属性配置。HttpClient客户端BeanMcpSyncClientclient(ObjectMapperobjectMapper,McpSyncHttpClientRequestCustomizerrequestCustomizer,McpClientCommonPropertiescommonProps){vartransportHttpClientStreamableHttpTransport.builder(mcpServerUrl).clientBuilder(HttpClient.newBuilder()).jsonMapper(newJacksonMcpJsonMapper(objectMapper)).httpRequestCustomizer(requestCustomizer).build();varclientInfonewMcpSchema.Implementation(client-name,commonProps.getVersion());returnMcpClient.sync(transport).clientInfo(clientInfo).requestTimeout(commonProps.getRequestTimeout()).transportContextProvider(newAuthenticationMcpTransportContextProvider()).build();}WebClient客户端BeanMcpSyncClientclient(WebClient.BuildermcpWebClientBuilder,ObjectMapperobjectMapper,McpClientCommonPropertiescommonProperties){varbuildermcpWebClientBuilder.baseUrl(mcpServerUrl);vartransportWebClientStreamableHttpTransport.builder(builder).jsonMapper(newJacksonMcpJsonMapper(objectMapper)).build();varclientInfonewMcpSchema.Implementation(clientName,commonProperties.getVersion());returnMcpClient.sync(transport).clientInfo(clientInfo).requestTimeout(commonProperties.getRequestTimeout()).transportContextProvider(newAuthenticationMcpTransportContextProvider()).build();}然后将客户端添加到ChatClient中varchatResponsechatClient.prompt(提示 LLM 执行操作).toolCallbacks(newSyncMcpToolCallbackProvider(mcpClient1,mcpClient2,mcpClient3)).call().content();3.7 已知限制限制说明WebFlux服务端不支持不支持Spring WebFlux服务端启动时自动初始化Spring AI自动配置在应用启动时初始化MCP客户端基于用户认证的场景需要绕过方案SSE兼容不同于服务端模块客户端实现支持SSE传输HttpClient和WebClient均可4. MCP 授权服务器MCP Authorization Server模块在Spring Security OAuth 2.0 Authorization Server基础上进行了增强新增了动态客户端注册Dynamic Client Registration和资源指示符Resource Indicators等MCP授权规范相关特性。4.1 依赖dependencygroupIdorg.springaicommunity/groupIdartifactIdmcp-authorization-server/artifactId/dependency4.2 配置在application.yml中配置授权服务器spring:application:name:sample-authorization-serversecurity:oauth2:authorizationserver:client:default-client:token:access-token-time-to-live:1hregistration:client-id:default-clientclient-secret:{noop}default-secretclient-authentication-methods:-client_secret_basic-noneauthorization-grant-types:-authorization_code-client_credentialsredirect-uris:-http://127.0.0.1:8080/authorize/oauth2/code/authserver-http://localhost:8080/authorize/oauth2/code/authserver# mcp-inspector-http://localhost:6274/oauth/callback# Claude Code-https://claude.ai/api/mcp/auth_callbackuser:# 单用户用户名为 username:userpassword:passwordserver:servlet:session:cookie:# 覆盖默认 cookie 名称JSESSIONID# 允许多个 Spring 应用在 localhost 上运行且各自拥有独立的 cookie# 否则由于 cookie 不考虑端口号会产生冲突name:MCP_AUTHORIZATION_SERVER_SESSIONID然后通过安全过滤器链激活授权服务器能力BeanSecurityFilterChainsecurityFilterChain(HttpSecurityhttp)throwsException{returnhttp// 所有请求均需认证.authorizeHttpRequests(auth-auth.anyRequest().authenticated())// 启用授权服务器自定义.with(McpAuthorizationServerConfigurer.mcpAuthorizationServer(),withDefaults())// 启用表单登录用户 user / password.formLogin(withDefaults()).build();}4.3 已知限制限制说明WebFlux不支持不支持Spring WebFlux服务端资源标识符所有客户端支持所有资源标识符resource identifiers5. 示例与集成samples目录包含所有模块的工作示例包括集成测试。通过mcp-server-security和配套的mcp-authorization-server可与以下工具集成CursorClaude DesktopMCP Inspector使用MCP Inspector时可能需要禁用CSRF和CORS保护。6. 参考资源MCP 授权规范MCP Security GitHub 仓库Spring Security OAuth 2.0 Resource ServerSpring Security OAuth 2.0 ClientSpring Authorization Server示例应用
Spring AI 1.x 系列【46】MCP Security 模块
发布时间:2026/6/8 20:10:59
1. 概述注意此模块仍处于开发阶段文档和 API 可能在后续版本中发生变更。Spring AI MCP Security模块为Spring AI的模型上下文协议MCP实现提供了全面的OAuth 2.0和API Key安全支持。该社区驱动的项目使开发者能够使用行业标准的认证与授权机制来保护MCP服务端和客户端。此模块属于spring-ai-community/mcp-security项目目前仅兼容Spring AI 1.1.x分支。它是社区驱动项目尚未获得Spring AI或MCP项目的官方背书。三大核心组件组件用途MCP Server Security为Spring AIMCP服务端提供OAuth 2.0资源服务器和API Key认证MCP Client Security为Spring AIMCP客户端提供OAuth 2.0客户端支持MCP Authorization Server基于Spring Authorization Server增强针对MCP场景定制核心能力使用OAuth 2.0和API Key保护MCP服务端为MCP客户端配置OAuth 2.0授权流程搭建专为MCP工作流设计的授权服务器实现对MCP工具和资源的细粒度访问控制2. MCP 服务端安全为Spring AIMCP服务端提供OAuth 2.0资源服务器能力同时提供基础的API Key认证支持。注意此模块仅兼容Spring WebMVC服务端。2.1 依赖dependenciesdependencygroupIdorg.springaicommunity/groupIdartifactIdmcp-server-security/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-security/artifactId/dependency!-- 可选OAuth2 支持 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-oauth2-resource-server/artifactId/dependency/dependencies2.2 OAuth 2.0 配置基础 OAuth 2.0 配置首先在application.properties中启用MCP服务端spring.ai.mcp.server.namemy-cool-mcp-server # 支持的协议STREAMABLE, STATELESS spring.ai.mcp.server.protocolSTREAMABLE然后使用Spring Security标准 API 结合MCP配置器进行安全配置ConfigurationEnableWebSecurityclassMcpServerConfiguration{Value(${spring.security.oauth2.resourceserver.jwt.issuer-uri})privateStringissuerUrl;BeanSecurityFilterChainsecurityFilterChain(HttpSecurityhttp)throwsException{returnhttp// 对 EVERY 请求强制要求 token 认证.authorizeHttpRequests(auth-auth.anyRequest().authenticated())// 在 MCP 服务端上配置 OAuth2.with(McpServerOAuth2Configurer.mcpServerOAuth2(),(mcpAuthorization)-{// 必填issuerURImcpAuthorization.authorizationServer(issuerUrl);// 可选强制校验 JWT 中的 aud 声明// 并非所有授权服务器都支持 resource indicators因此可能缺失// 默认值为 false// 参见 RFC 8707 Resource Indicators for OAuth 2.0mcpAuthorization.validateAudienceClaim(true);}).build();}}仅保护工具调用可以配置服务端仅对工具调用进行安全保护其他MCP操作如initialize、tools/list保持公开ConfigurationEnableWebSecurityEnableMethodSecurity// 启用注解驱动的安全classMcpServerConfiguration{Value(${spring.security.oauth2.resourceserver.jwt.issuer-uri})privateStringissuerUrl;BeanSecurityFilterChainsecurityFilterChain(HttpSecurityhttp)throwsException{returnhttp// 开放服务端上的所有请求.authorizeHttpRequests(auth-{auth.requestMatcher(/mcp).permitAll();auth.anyRequest().authenticated();})// 在 MCP 服务端上配置 OAuth2.with(McpResourceServerConfigurer.mcpServerOAuth2(),(mcpAuthorization)-{// 必填issuerURImcpAuthorization.authorizationServer(issuerUrl);}).build();}}然后使用PreAuthorize注解结合方法安全来保护工具调用ServicepublicclassMyToolsService{PreAuthorize(isAuthenticated())McpTool(namegreeter,description用你选择的语言向你问好)publicStringgreet(ToolParam(description问好的语言例english、french…)Stringlanguage){if(!StringUtils.hasText(language)){language;}returnswitch(language.toLowerCase()){caseenglish-Hello you!;casefrench-Salut toi!;default-我不懂 \%s\ 语言所以只能说 Hello.formatted(language);};}}也可以通过SecurityContextHolder在工具方法中直接访问当前认证信息McpTool(namegreeter,description用指定语言向用户称呼名字问好)PreAuthorize(isAuthenticated())publicStringgreet(ToolParam(description问好的语言例english、french…)Stringlanguage){if(!StringUtils.hasText(language)){language;}varauthenticationSecurityContextHolder.getContext().getAuthentication();varnameauthentication.getName();returnswitch(language.toLowerCase()){caseenglish-Hello, %s!.formatted(name);casefrench-Salut %s!.formatted(name);default-(我不懂 \%s\ 语言所以只能说 Hello %s).formatted(language,name);};}2.3 API Key 认证MCP Server Security模块也支持基于API Key的认证。你需要提供自己的ApiKeyEntityRepository实现来存储ApiKeyEntity对象。框架提供了InMemoryApiKeyEntityRepository示例实现和默认的ApiKeyEntityImpl注意InMemoryApiKeyEntityRepository使用bcrypt存储API Key计算开销较高不适合高并发生产环境。生产环境请实现自己的ApiKeyEntityRepository。ConfigurationEnableWebSecurityclassMcpServerConfiguration{BeanSecurityFilterChainsecurityFilterChain(HttpSecurityhttp)throwsException{returnhttp.authorizeHttpRequests(authz-authz.anyRequest().authenticated()).with(mcpServerApiKey(),(apiKey)-{// 必填API Key 的存储仓库apiKey.apiKeyRepository(apiKeyRepository());// 可选携带 API Key 的请求头名称// 例如此处API Key 将通过 CUSTOM-API-KEY: value 发送// 替代 .authenticationConverter(...)见下方//// apiKey.headerName(CUSTOM-API-KEY);// 可选自定义转换器将 HTTP 请求转为认证对象// 适用于 header 为 Authorization: Bearer value 的场景// 替代 .headerName(...)见上方//// apiKey.authenticationConverter(request - {// var key extractKey(request);// return ApiKeyAuthenticationToken.unauthenticated(key);// });}).build();}/** * 提供 {link ApiKeyEntity} 的存储仓库 */privateApiKeyEntityRepositoryApiKeyEntityImplapiKeyRepository(){varapiKeyApiKeyEntityImpl.builder().name(test api key).id(api01).secret(mycustomapikey).build();returnnewInMemoryApiKeyEntityRepository(List.of(apiKey));}}配置完成后可通过请求头X-API-key: api01.mycustomapikey调用MCP服务端。2.4 已知限制限制说明SSE不支持已弃用的SSE传输不受支持请使用Streamable HTTP或Stateless传输WebFlux不支持不支持基于WebFlux的服务端Opaque Token不支持请使用JWT3. MCP 客户端安全为Spring AIMCP客户端提供OAuth 2.0支持同时兼容基于HttpClient的客户端spring-ai-starter-mcp-client和基于WebClient的客户端spring-ai-starter-mcp-client-webflux。注意此模块仅支持McpSyncClient。3.1 依赖dependencygroupIdorg.springaicommunity/groupIdartifactIdmcp-client-security/artifactId/dependency3.2 授权流程三种OAuth 2.0授权流程可供选择流程适用场景授权码流程authorization_code用户级别权限所有MCP请求均在用户请求上下文中发起客户端凭证流程client_credentials机器对机器通信无人工参与混合流程Hybrid部分操作如initialize、tools/list无需用户在场即可执行但工具调用需要用户级别权限选择建议当使用Spring Boot属性配置MCP客户端时推荐使用混合流程因为工具发现是在启动时进行的此时并无用户在场。3.3 通用配置所有流程都需要在application.properties中激活Spring SecurityOAuth2客户端支持# 确保 MCP 客户端为同步模式spring.ai.mcp.client.typeSYNC# 授权码流程或混合流程spring.security.oauth2.client.registration.authserver.client-id客户端IDspring.security.oauth2.client.registration.authserver.client-secret客户端密钥spring.security.oauth2.client.registration.authserver.authorization-grant-typeauthorization_code spring.security.oauth2.client.registration.authserver.providerauthserver# 客户端凭证流程或混合流程spring.security.oauth2.client.registration.authserver-client-credentials.client-id客户端IDspring.security.oauth2.client.registration.authserver-client-credentials.client-secret客户端密钥spring.security.oauth2.client.registration.authserver-client-credentials.authorization-grant-typeclient_credentials spring.security.oauth2.client.registration.authserver-client-credentials.providerauthserver# 授权服务器配置spring.security.oauth2.client.provider.authserver.issuer-uri授权服务器的ISSUER URI然后创建配置类激活OAuth2客户端能力ConfigurationEnableWebSecurityclassSecurityConfiguration{BeanSecurityFilterChainsecurityFilterChain(HttpSecurityhttp)throwsException{returnhttp// 此示例中客户端应用自身端点无安全保护.authorizeHttpRequests(auth-auth.anyRequest().permitAll())// 开启 OAuth2 支持.oauth2Client(Customizer.withDefaults()).build();}}3.4 HttpClient 客户端使用spring-ai-starter-mcp-client时配置McpSyncHttpClientRequestCustomizerBeanConfigurationclassMcpConfiguration{BeanMcpSyncClientCustomizersyncClientCustomizer(){return(name,syncSpec)-syncSpec.transportContextProvider(newAuthenticationMcpTransportContextProvider());}BeanMcpSyncHttpClientRequestCustomizerrequestCustomizer(OAuth2AuthorizedClientManagerclientManager){// clientRegistration 名称 authserver 须与 application.properties 中一致returnnewOAuth2AuthorizationCodeSyncHttpRequestCustomizer(clientManager,authserver);}}可用的Customizer实现类对应流程OAuth2AuthorizationCodeSyncHttpRequestCustomizer授权码流程OAuth2ClientCredentialsSyncHttpRequestCustomizer客户端凭证流程OAuth2HybridSyncHttpRequestCustomizer混合流程3.5 WebClient 客户端使用spring-ai-starter-mcp-client-webflux时通过MCP ExchangeFilterFunction配置WebClient.BuilderConfigurationclassMcpConfiguration{BeanMcpSyncClientCustomizersyncClientCustomizer(){return(name,syncSpec)-syncSpec.transportContextProvider(newAuthenticationMcpTransportContextProvider());}BeanWebClient.BuildermcpWebClientBuilder(OAuth2AuthorizedClientManagerclientManager){// clientRegistration 名称 authserver 须与 application.properties 中一致returnWebClient.builder().filter(newMcpOAuth2AuthorizationCodeExchangeFilterFunction(clientManager,authserver));}}可用的Filter实现类对应流程McpOAuth2AuthorizationCodeExchangeFilterFunction授权码流程McpOAuth2ClientCredentialsExchangeFilterFunction客户端凭证流程McpOAuth2HybridExchangeFilterFunction混合流程3.6 绕过 Spring AI 自动配置Spring AI的自动配置会在启动时初始化MCP客户端这可能导致基于用户认证的场景出问题。以下提供两种绕过方案方案一禁用 Tool 自动配置发布一个空的ToolCallbackResolverBean 来禁用Spring AI的Tool自动配置ConfigurationpublicclassMcpConfiguration{BeanToolCallbackResolverresolver(){returnnewStaticToolCallbackResolver(List.of());}}方案二编程式客户端配置以编程方式配置MCP客户端替代Spring Boot属性配置。HttpClient客户端BeanMcpSyncClientclient(ObjectMapperobjectMapper,McpSyncHttpClientRequestCustomizerrequestCustomizer,McpClientCommonPropertiescommonProps){vartransportHttpClientStreamableHttpTransport.builder(mcpServerUrl).clientBuilder(HttpClient.newBuilder()).jsonMapper(newJacksonMcpJsonMapper(objectMapper)).httpRequestCustomizer(requestCustomizer).build();varclientInfonewMcpSchema.Implementation(client-name,commonProps.getVersion());returnMcpClient.sync(transport).clientInfo(clientInfo).requestTimeout(commonProps.getRequestTimeout()).transportContextProvider(newAuthenticationMcpTransportContextProvider()).build();}WebClient客户端BeanMcpSyncClientclient(WebClient.BuildermcpWebClientBuilder,ObjectMapperobjectMapper,McpClientCommonPropertiescommonProperties){varbuildermcpWebClientBuilder.baseUrl(mcpServerUrl);vartransportWebClientStreamableHttpTransport.builder(builder).jsonMapper(newJacksonMcpJsonMapper(objectMapper)).build();varclientInfonewMcpSchema.Implementation(clientName,commonProperties.getVersion());returnMcpClient.sync(transport).clientInfo(clientInfo).requestTimeout(commonProperties.getRequestTimeout()).transportContextProvider(newAuthenticationMcpTransportContextProvider()).build();}然后将客户端添加到ChatClient中varchatResponsechatClient.prompt(提示 LLM 执行操作).toolCallbacks(newSyncMcpToolCallbackProvider(mcpClient1,mcpClient2,mcpClient3)).call().content();3.7 已知限制限制说明WebFlux服务端不支持不支持Spring WebFlux服务端启动时自动初始化Spring AI自动配置在应用启动时初始化MCP客户端基于用户认证的场景需要绕过方案SSE兼容不同于服务端模块客户端实现支持SSE传输HttpClient和WebClient均可4. MCP 授权服务器MCP Authorization Server模块在Spring Security OAuth 2.0 Authorization Server基础上进行了增强新增了动态客户端注册Dynamic Client Registration和资源指示符Resource Indicators等MCP授权规范相关特性。4.1 依赖dependencygroupIdorg.springaicommunity/groupIdartifactIdmcp-authorization-server/artifactId/dependency4.2 配置在application.yml中配置授权服务器spring:application:name:sample-authorization-serversecurity:oauth2:authorizationserver:client:default-client:token:access-token-time-to-live:1hregistration:client-id:default-clientclient-secret:{noop}default-secretclient-authentication-methods:-client_secret_basic-noneauthorization-grant-types:-authorization_code-client_credentialsredirect-uris:-http://127.0.0.1:8080/authorize/oauth2/code/authserver-http://localhost:8080/authorize/oauth2/code/authserver# mcp-inspector-http://localhost:6274/oauth/callback# Claude Code-https://claude.ai/api/mcp/auth_callbackuser:# 单用户用户名为 username:userpassword:passwordserver:servlet:session:cookie:# 覆盖默认 cookie 名称JSESSIONID# 允许多个 Spring 应用在 localhost 上运行且各自拥有独立的 cookie# 否则由于 cookie 不考虑端口号会产生冲突name:MCP_AUTHORIZATION_SERVER_SESSIONID然后通过安全过滤器链激活授权服务器能力BeanSecurityFilterChainsecurityFilterChain(HttpSecurityhttp)throwsException{returnhttp// 所有请求均需认证.authorizeHttpRequests(auth-auth.anyRequest().authenticated())// 启用授权服务器自定义.with(McpAuthorizationServerConfigurer.mcpAuthorizationServer(),withDefaults())// 启用表单登录用户 user / password.formLogin(withDefaults()).build();}4.3 已知限制限制说明WebFlux不支持不支持Spring WebFlux服务端资源标识符所有客户端支持所有资源标识符resource identifiers5. 示例与集成samples目录包含所有模块的工作示例包括集成测试。通过mcp-server-security和配套的mcp-authorization-server可与以下工具集成CursorClaude DesktopMCP Inspector使用MCP Inspector时可能需要禁用CSRF和CORS保护。6. 参考资源MCP 授权规范MCP Security GitHub 仓库Spring Security OAuth 2.0 Resource ServerSpring Security OAuth 2.0 ClientSpring Authorization Server示例应用