Spring AI框架提供了对Model Context Protocol(简称MCP)的全面支持,使AI模型能够以标准化方式与外部工具和资源进行安全交互。借助Spring AI,开发者仅需少量代码即可构建功能完备的MCP服务器,为AI模型提供丰富的功能扩展。
MCP 中的授权和安全
MCP服务器默认支持通过STDIO传输在本地环境中运行。当需要将服务公开至网络环境时,则必须通过HTTP端点提供服务。虽然私有部署场景下可能无需严格的身份验证机制,但在企业级应用中,必须实施完善的安全防护和权限管理体系。2025年3月26日发布的最新MCP规范版本(2025-03-26)针对这一需求,基于业界广泛采用的OAuth2框架,为客户端与服务器间的安全通信建立了标准规范。
在深入实现细节前,让我们简要回顾OAuth2的核心概念。根据规范草案,MCP服务器需要同时承担资源服务器和授权服务器双重角色:
作为 资源服务器,它通过验证请求头中的Authorization字段执行访问控制。该字段必须包含有效的OAuth2访问令牌(access_token),这个令牌可以是自包含的JSON Web Token(JWT),也可以是需验证的不透明字符串。当令牌缺失或无效(如格式错误、过期或接收方不匹配)时,服务器将拒绝请求。典型的安全请求示例如下:
curl https://mcp.example.com/sse -H "Authorization: Bearer <a valid access token>"
作为授权服务器,MCP服务还需安全地颁发访问令牌。在令牌发放前,服务器会验证客户端凭证,某些场景下还需确认终端用户身份。授权服务器同时负责定义令牌属性,包括有效期、作用域(scope)和目标受众(audience)等关键参数。
借助Spring Security和Spring Authorization Server,我们可以为现有Spring MCP服务添加这两类安全能力。

image.png
为 Spring MCP 服务器添加 OAuth2
本示例基于Spring AI开发的一个图书的Mcp Server,代码如下:
@Service
@Slf4j
publicclass BookService {
/**
* 查询图书信息
* @param bookName 图书名称
* @return 图书信息
*/
@Tool(description = "查询图书信息")
@SneakyThrows
public BookInfo getBookInfo(@ToolParam(description = "图书名称") String bookName,@ToolParam(description = "图书ID") Long bookId) {
// 构建一个静态BookInfo对象,只有bookName是根据参数传入的
return BookInfo.builder()
.xxxx()
.build();
}
/**
* 获取图书列表
* @param limit 返回数量限制
* @return 图书列表
*/
@Tool(description = "获取图书列表")
@SneakyThrows
public List<BookInfo> getBookList(@ToolParam(description = "返回数量限制,默认10") Integer limit) {
......
return bookList;
}
}
BookService中暴露了两个Mcp Tool,一个用于获取图书的详细信息,一个用于获取图书的列表。本文重点在于演示如何为其添加OAuth2安全支持,暂不涉及客户端交互细节。
第一步:添加依赖配置
在项目的pom.xml中引入必要的Spring Boot starter:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-authorization-server</artifactId>
</dependency>
第二步:配置OAuth2客户端
在OAuth2ClientConfig
配置类中配置基础客户端信息,用于后续的令牌获取测试:
@Bean
public RegisteredClientRepository registeredClientRepository() {
RegisteredClient mcpClient = RegisteredClient.withId(UUID.randomUUID().toString())
.clientId("mcp-client")
.clientSecret("{noop}secret")
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
.tokenSettings(TokenSettings.builder()
.accessTokenTimeToLive(Duration.ofHours(1))
.build())
.clientSettings(ClientSettings.builder()
.requireAuthorizationConsent(false)
.build())
.scope("LIST")
.build();
returnnew InMemoryRegisteredClientRepository(mcpClient);
}
此配置定义了一个使用客户端凭证模式(client_credentials)的基础客户端,采用HTTP Basic认证方式,凭证硬编码为mcp-client/secret。
第三步:实现安全配置
创建安全配置类SecurityConfiguration,通过定义SecurityFilterChain Bean来启用安全功能:
import static org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer.authorizationServer;
@Configuration
@EnableWebSecurity
class SecurityConfiguration {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http.authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
.with(authorizationServer(), Customizer.withDefaults())
.oauth2ResourceServer(resource -> resource.jwt(Customizer.withDefaults()))
.csrf(CsrfConfigurer::disable)
.cors(Customizer.withDefaults())
.build();
}
}
该配置实现了以下安全策略:
-
强制所有请求必须经过认证
-
同时启用授权服务器和资源服务器功能
-
禁用CSRF防护(适用于非浏览器交互场景)
-
启用CORS支持(便于使用MCP检查器测试)
服务验证测试
完成配置后,未经认证的请求将被拒绝,并显示 HTTP 401 Unauthorized
错误
curl http://localhost:8080/sse --fail-with-body
#
# Response:
#
# curl: (22) The requested URL returned error: 401
要使用MCP 服务器,我们首先需要获取一个访问令牌。我们使用 client_credentials
OAuth2 授权类型,这用于"机器对机器"或"服务账户"场景:
curl -XPOST http://localhost:8080/oauth2/token --data grant_type=client_credentials --user mcp-client:secret
#
# Response:
#
# {"access_token":"<YOUR-ACCESS-TOKEN>","token_type":"Bearer","expires_in":3599}%
复制 access_token
的值,它以字母"ey"开头。现在我们可以使用这个访问令牌发出请求,它们应该能成功。例如使用 curl
,您可以将 YOUR_ACCESS_TOKEN
替换为您上面复制的值:
curl http://localhost:8080/sse -H"Authorization: Bearer YOUR_ACCESS_TOKEN"
#
# Response:
#
# id:918d5ebe-9ae5-4b04-aae8-c1ff8cdbb6e0
# event:endpoint
# data:/mcp/message?sessionId=918d5ebe-9ae5-4b04-aae8-c1ff8cdbb6e0
从版本 0.6.0
开始,也可以直接在 mcp inspector
中使用访问令牌。只需启动检查器,并将访问令牌粘贴到左侧菜单中的"Authentication > Bearer"字段中。即可建立安全连接。

image.png
进阶安全方案展望
目前来看,SpringAi Mcp的oauth2集成方案只能通过客户端模式与SSE进行安全连接,无法对单个tool进行精细化权限控制。接下来主要有两个方向:
-
客户端认证升级:增强MCP客户端功能,使其支持"授权码模式"(Authorization Code Grant)。该模式允许终端用户使用个人凭证登录,获取用户绑定的访问令牌,为实现基于角色的访问控制(RBAC)等精细化权限管理奠定基础。
-
分布式认证架构:探索集成外部专业OAuth2授权服务器的方案,使MCP服务器仅需专注于资源服务器功能的实现。