一、MCP 鉴权概述

MCP (Model Context Protocol) 旨在为大语言模型(LLM)与外部数据源、工具和服务提供标准化、安全的集成方式(相当于一种专用的 RPC 协议)。广泛应用于 AI 开发中的工具服务(Tool)、提示语服务(Prompt)和资源服务(Resource)。在实际应用中,确保 MCP 服务的安全性至关重要,因此需要合理的鉴权机制。

根据提供的资料,MCP 鉴权主要涉及以下几个方面:

  • 服务端鉴权设计
  • 客户端鉴权配置
  • 不同通讯通道(stdio/SSE)的鉴权实现
  • 与 Web API 互通的鉴权处理

本案基于 Solon AI MCP 进行鉴权方面的探讨:

<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-ai-mcp</artifactId>
<version>最新版本</version>
</dependency>

可支持 java8, java11, java17, java21, java24 。可支持 solon,springboot,vert.x,jFinal 等框架集成。

二、MCP 服务端鉴权设计

1、基于过滤器的鉴权方案

MCP 服务端可以通过过滤器或路由拦截器实现鉴权,特别是对于 HTTP SSE 通道的服务:

@Component
public class McpFilter implements Filter {
@Override
public void doFilter(Context ctx, FilterChain chain) throws Throwable {
//message 端点,不需要鉴权
if (ctx.pathNew().startsWith("/mcp/") && ctx.pathNew().endsWith("/message") == false) {
String authStr = ctx.header("Authorization");
if (Utils.isEmpty(authStr)) {
ctx.status(401);
return;
}
// 业务检测逻辑
if (!checkAuth(authStr)) {
ctx.status(403);
return;
}
} chain.doFilter(ctx);
} private boolean checkAuth(String authStr) {
// 实现具体的鉴权逻辑
return true;
}
}

2、基于注解的端点级鉴权

对于使用 @McpServerEndpoint 注解的服务端点,可以通过 @Header 注解或者 上下文对象(Context) 获取用户身份或鉴权信息:

@McpServerEndpoint(sseEndpoint = "/mcp/sse")
public class McpAuthService { @ToolMapping(description = "需要鉴权的天气预报查询")
public String getWeather(@Param(description = "城市位置") String location, @Header("user") user, Context ctx) {
// 根据用户隔离数据: user // 从上下文中获取鉴权或身份信息: ctx return "晴,14度";
}
}

在方法里鉴权时不能输出状态码,要改为异常抛出。

三、MCP 客户端鉴权配置

1、Basic Authentication

McpClientProvider toolProvider = McpClientProvider.builder()
.apiUrl("https://localhost:8080/mcp/sse")
.apiKey("sk-xxxxx") // 自动转换为Authorization头
.build();

2、自定义 Header 鉴权

McpClientProvider toolProvider = McpClientProvider.builder()
.apiUrl("https://localhost:8080/mcp/sse")
.header("X-API-KEY", "your-api-key")
.header("X-API-SECRET", "your-api-secret")
.header("X-USER", "your-user")
.build();

3、QueryString 参数鉴权(比较常见)

McpClientProvider toolProvider = McpClientProvider.builder()
.apiUrl("https://localhost:8080/mcp/sse?token=xxxx")
.build();

四、不同通道的鉴权实现

1、HTTP SSE 通道鉴权

HTTP SSE 通道的鉴权可以利用 HTTP 协议本身的特性:

@Configuration
public class McpSseAuthConfig { @Bean
public McpClientProvider sseClient() {
return McpClientProvider.builder()
.apiUrl("http://localhost:8080/mcp/sse")
.header("X-Auth-Token", "your-token")
.httpTimeout(HttpTimeout.builder()
.connectTimeout(Duration.ofSeconds(10))
.readTimeout(Duration.ofSeconds(60))
.build())
.build();
}
}

2、2. STDIO 通道鉴权

对于 STDIO 通道,鉴权通常通过环境变量或启动参数实现:

@McpServerEndpoint(channel = McpChannel.STDIO)
public class StdioAuthService { @ToolMapping(description = "STDIO通道的鉴权服务")
public String secureOperation(@Param String input) {
String authToken = System.getenv("INTERNAL_AUTH_TOKEN");
if(!validateInternalToken(authToken)) {
throw new SecurityException("Invalid internal token");
} return processInput(input);
}
}

客户端调用时配置环境变量:

McpClientProvider stdioClient = McpClientProvider.builder()
.channel(McpChannel.STDIO)
.serverParameters(ServerParameters.builder("java")
.args("-jar", "secure-service.jar")
.addEnvVar("INTERNAL_AUTH_TOKEN", "secure-token-value")
.build())
.build();

五、与 Web API 互通的鉴权

MCP 服务可以与 Web API 互通,共享鉴权逻辑:

@Mapping("/api/secure")
@Controller
@McpServerEndpoint(sseEndpoint = "/mcp/secure/sse")
public class HybridAuthService { @ToolMapping(description = "混合鉴权服务")
@Mapping("operation")
public String hybridOperation(
@Param(description = "输入参数") String input,
@Header("Authorization") String authHeader) { if(!validateAuthHeader(authHeader)) {
throw new SecurityException("Unauthorized");
} return "Processed: " + input;
}
}

六、最佳实践与注意事项

多因素认证:对于高安全性要求的场景,可以结合多种鉴权方式

McpClientProvider highSecClient = McpClientProvider.builder()
.apiUrl("https://secure.example.com/mcp/sse")
.apiKey("primary-key")
.header("X-Second-Factor", "totp-code")
.build();

敏感信息保护:避免在日志中输出鉴权信息

// 开发 stdio 服务时特别重要
@McpServerEndpoint(channel = McpChannel.STDIO)
public class SecureStdioService {
// 确保不打印敏感信息到控制台
}

性能考虑:对于高频调用的服务,采用高效的鉴权方案

// 使用高效的JWT验证
public class JwtAuthFilter implements Filter {
// 实现快速的JWT验证逻辑
}

七、完整示例:带鉴权的 MCP 服务

服务端实现

// 鉴权配置类
@Configuration
public class McpAuthConfig { @Bean
public Filter mcpAuthFilter() {
return new McpAuthFilter();
}
} // 鉴权过滤器
public class McpAuthFilter implements Filter {
@Override
public void doFilter(Context ctx, FilterChain chain) throws Throwable {
if (ctx.pathNew().startsWith("/mcp/") && ctx.pathNew().endsWith("/message") == false) {
String token = ctx.header("X-Auth-Token");
if (!"valid-token".equals(token)) {
ctx.status(401).output("Unauthorized");
return;
}
}
chain.doFilter(ctx);
}
} // MCP服务端点
@McpServerEndpoint(sseEndpoint = "/mcp/secure/sse")
public class SecureMcpService { @ToolMapping(description = "安全操作")
public String secureOp(@Param(description = "输入") String input) {
return "Secure result for: " + input;
}
}

客户端实现

public class SecureMcpClient {

    private final McpClientProvider client;

    public SecureMcpClient() {
this.client = McpClientProvider.builder()
.apiUrl("http://localhost:8080/mcp/secure/sse")
.header("X-Auth-Token", "valid-token")
.requestTimeout(Duration.ofSeconds(20))
.build();
} public String callSecureOp(String input) {
return client.callToolAsText("secureOp", Map.of("input", input));
}
}

总结

MCP 鉴权是保障服务安全性的重要环节,通过本文介绍的服务端过滤器、客户端配置、不同通道实现等方式,可以构建灵活安全的鉴权体系。在实际应用中,应根据具体场景选择适合的鉴权方案,并遵循安全最佳实践,确保 MCP 服务的安全可靠运行。

Java MCP 鉴权设计与实现指南的更多相关文章

  1. # RESTful登录(基于token鉴权)的设计实例

    使用场景 现在很多基于restful的api接口都有个登录的设计,也就是在发起正式的请求之前先通过一个登录的请求接口,申请一个叫做token的东西.申请成功后,后面其他的支付请求都要带上这个token ...

  2. Spring Security 接口认证鉴权入门实践指南

    目录 前言 SpringBoot 示例 SpringBoot pom.xml SpringBoot application.yml SpringBoot IndexController SpringB ...

  3. RESTful登录设计(基于Spring及Redis的Token鉴权)

    转载自:http://www.scienjus.com/restful-token-authorization/ http://m.blog.csdn.net/article/details?id=4 ...

  4. spring boot / cloud (十四) 微服务间远程服务调用的认证和鉴权的思考和设计,以及restFul风格的url匹配拦截方法

    spring boot / cloud (十四) 微服务间远程服务调用的认证和鉴权的思考和设计,以及restFul风格的url匹配拦截方法 前言 本篇接着<spring boot / cloud ...

  5. PHP SoapClient 调用与鉴权,以及对Java和C# 的webservice的兼容处理

    SoapClient使用注意事项: 第一要加上 cache_wsdl参数,以防服务器调用的是缓存的wsdl文件 然后是参数传递,如果是使用PHP自己写的WebService,参数传递按正常方式即可 1 ...

  6. 认证鉴权与API权限控制在微服务架构中的设计与实现(四)

    引言: 本文系<认证鉴权与API权限控制在微服务架构中的设计与实现>系列的完结篇,前面三篇已经将认证鉴权与API权限控制的流程和主要细节讲解完.本文比较长,对这个系列进行收尾,主要内容包括 ...

  7. 阿里云直播鉴权java代码示例

    段时间公司需要做直播服务,所以就研究了一下阿里云的直播,在直播里面,最重要的就是url的鉴权操作(验证推流或者拉流的有效性),在网上找了很多代码,都没有发现java的demo,所以就写篇播客记录一下, ...

  8. apigw鉴权分析(1-4)新浪微博开放平台 - 鉴权分析

    一.访问入口 http://open.weibo.com/wiki/%E6%8E%88%E6%9D%83%E6%9C%BA%E5%88%B6%E8%AF%B4%E6%98%8E 微博开放接口的调用,如 ...

  9. Shiro(4)默认鉴权与自定义鉴权

    =========默认鉴权======== 过滤链中定义: <!-- 过滤链定义 --> <property name="filterChainDefinitions&qu ...

  10. Spring Boot整合实战Spring Security JWT权限鉴权系统

    目前流行的前后端分离让Java程序员可以更加专注的做好后台业务逻辑的功能实现,提供如返回Json格式的数据接口就可以.像以前做项目的安全认证基于 session 的登录拦截,属于后端全栈式的开发的模式 ...

随机推荐

  1. 11. RabbitMQ 消息队列 Federation (Exchange 交换机和 Queue队列) + Shovel 同步的搭建配置

    11. RabbitMQ 消息队列 Federation (Exchange 交换机和 Queue队列) + Shovel 同步的搭建配置 @ 目录 11. RabbitMQ 消息队列 Federat ...

  2. MySQL 中 DATETIME 和 TIMESTAMP 类型的区别是什么?

    在MySQL中,DATETIME和TIMESTAMP都是用于存储日期和时间的类型,但它们有一些关键的区别: 1. 存储方式和范围 DATETIME: 存储的日期和时间值是以"年-月-日 时: ...

  3. 开发 MCP Proxy(代理)也可以用 Solon AI MCP 哟!

    MCP 有三种通讯方式: 通道 说明 备注 stdio 本地进程内通讯 现有 sse http 远程 http 通讯 现有 streamable http 远程 http 通讯 (MCP 官方刚通过决 ...

  4. 『Plotly实战指南』--交互功能基础篇

    在数据可视化领域,静态图表早已无法满足用户对深度分析与探索的需求. Plotly作为新一代交互式可视化工具,通过其强大的交互功能重新定义了"数据叙事"的边界. 通过精心设计的交互功 ...

  5. <HarmonyOS第一课12>Web组件和WebView #鸿蒙课程##鸿蒙生态#

    课程介绍 <HarmonyOS第一课:Web组件和WebView>是一门专为HarmonyOS开发者设计的课程,旨在掌握如何在应用中集成Web内容.课程首先介绍了基于Web技术的Web组件 ...

  6. Nacos源码—4.Nacos集群高可用分析二

    大纲 6.CAP原则与Raft协议 7.Nacos实现的Raft协议是如何写入数据的 8.Nacos实现的Raft协议是如何选举Leader节点的 9.Nacos实现的Raft协议是如何同步数据的 1 ...

  7. Queue接口分析

    一.Queue是什么 该接口时Java集合框架成员 Queue: 通常(但不一定)队列就是一个先入先出(FIFO)的数据结构,和堆一样(但可以进行转换,比如优先级列队排序,又或者改为栈形式的后进先出数 ...

  8. centos6分区要点

    安装centos6系统时,为了以后能够扩展存储,分区时要注意几点: 1.boot引导分区要选固定分区类型存储,大小是500M 2.其余分区全部做成物理卷lvm  pyshiic类型存储 3.在这个物理 ...

  9. VUE构建

    VUE 渐进式 JavaScript 框架 易学易用 基于标准 HTML.CSS 和 JavaScript 构建,提供容易上手的 API 和一流的文档. 性能出色 经过编译器优化.完全响应式的渲染系统 ...

  10. codeup之C语言10.1+C语言10.2(指针

    Description 输入a和b两个整数,按先大后小的顺序输出a和b.注意请使用指针变量的方式进行比较和输出. Input 两个用空格隔开的整数a和b. Output 按先大后小的顺序输出a和b,用 ...