继续先前的MCP学习,实际企业级应用中,很多信息都是涉及商业敏感数据,需要考虑安全认证,不可能让MCP Server在网上裸奔。spring web开发中,提供了拦截器功能,最简单的思路,在Client连接到Server的sse时,拦截请求,检测http header头中,是否有必要的token信息(包括验证token是否合法)

这次,我们使用spring web mvc来创建mcp server.

一、调整pom.xml

 1     <dependencyManagement>
2 <dependencies>
3 <dependency>
4 <groupId>org.springframework.ai</groupId>
5 <artifactId>spring-ai-bom</artifactId>
6 <!--目前只有snapshot版本的mcp webmvc功能正常-->
7 <version>1.1.0-SNAPSHOT</version>
8 <type>pom</type>
9 <scope>import</scope>
10 </dependency>
11 </dependencies>
12 </dependencyManagement>
13
14 <dependencies>
15 <dependency>
16 <groupId>org.springframework.ai</groupId>
17 <artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
18 </dependency>
19 </dependencies>
20
21 <build>
22 <plugins>
23 <plugin>
24 <groupId>org.springframework.boot</groupId>
25 <artifactId>spring-boot-maven-plugin</artifactId>
26 </plugin>
27 </plugins>
28 </build>
29
30 <repositories>
31 <repository>
32 <id>spring-milestones</id>
33 <name>Spring Milestones</name>
34 <url>https://repo.spring.io/milestone</url>
35 <snapshots>
36 <enabled>false</enabled>
37 </snapshots>
38 </repository>
39 <repository>
40 <id>spring-snapshots</id>
41 <name>Spring Snapshots</name>
42 <url>https://repo.spring.io/snapshot</url>
43 <releases>
44 <enabled>false</enabled>
45 </releases>
46 </repository>
47 <repository>
48 <id>central-portal-snapshots</id>
49 <name>Central Portal Snapshots</name>
50 <url>https://central.sonatype.com/repository/maven-snapshots/</url>
51 <releases>
52 <enabled>false</enabled>
53 </releases>
54 <snapshots>
55 <enabled>true</enabled>
56 </snapshots>
57 </repository>
58 </repositories>

注:目前只有SNAPSHOT的spring-ai-starter-mcp-server-webmvc能运行正常。

二、添加1个拦截器

@Component
public class Interceptor implements HandlerInterceptor { @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String authorization = request.getHeader("Authorization");
if (authorization == null || !authorization.startsWith("Bearer ")) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return false;
}
//模拟几个账号123456,234567,允许访问,其它拒绝
String token = authorization.substring(7);
if ("123456".equals(token) || "234567".equals(token)) {
return true;
}
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return false;
}
}

三、注册拦截器

@Configuration
public class WebConfig implements WebMvcConfigurer { @Autowired
private Interceptor interceptor; @Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(interceptor)
.addPathPatterns("/sse","/mcp/messages");
}
}

启动后,再访问http://localhost:8080/sse,会得到1个401的错误码

在CherryStudio中设置时,必须添加正确的请求头,才能保存成功

有了正确的请求头,就能正常调用MCP Server了

tips: 实际企业级应用中,涉及敏感信息的系统,往往会要求用户先登录认证,登录成功后将token放到cookie里,后续请求MCP时,将该token在上下文中放到http header里即可。

参考:

Transports - Model Context Protocol

spring-ai-examples/model-context-protocol/weather/starter-webmvc-server at main · spring-projects/spring-ai-examples

spring-ai 学习系列(7)-MCP 安全认证的更多相关文章

  1. Spring Boot 学习系列(10)—SpringBoot+JSP的使

    此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 解决问题 随着spring boot 框架的逐步使用,我们期望对于一些已有的系统进行改造,做成通用的脚手架, ...

  2. Spring Boot 学习系列(03)—jar or war,做出你的选择

    此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 两种打包方式 采用Spring Boot框架来构建项目,我们对项目的打包有两种方式可供选择,一种仍保持原有的 ...

  3. Spring Boot 学习系列(序)—Spring Boot

    此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. Spring Boot? Spring Boot 是由pivotal团队提供的一个基于Spring的全新框架 ...

  4. Spring Boot 学习系列(06)—采用log4j2记录日志

    此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 为什么选择log4j2 log4j2相比于log4j1.x和logback来说,具有更快的执行速度.同时也支 ...

  5. Spring Boot 学习系列(05)—自定义视图解析规则

    此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 自定义视图解析 在默认情况下Spring Boot 的MVC框架使用的视图解析ViewResolver类是C ...

  6. Spring Boot 学习系列(09)—自定义Bean的顺序加载

    此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. Bean 的顺序加载 有些场景中,我们希望编写的Bean能够按照指定的顺序进行加载.比如,有UserServ ...

  7. Spring Boot 学习系列(08)—自定义servlet、filter及listener

    此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 传统的filter及listener配置 在传统的Java web项目中,servlet.filter和li ...

  8. Spring Boot 学习系列(07)—properties文件读取

    此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 传统的properties读取方式 一般的,我们都可以自定义一个xxx.properties文件,然后在工程 ...

  9. Spring Boot 学习系列(04)—分而治之,多module打包

    此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 明确功能,各司其职 在一个结构清晰的项目中,一个没有module划分的结构显然不是最佳实践.有人会说可以在同 ...

  10. Spring Boot 学习系列(01)—从0到1,只需两分钟

    此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 快速构建 如果我们想基于spring mvc 提供一个简单的API查询服务,传统的方式,首先需要我们引入sp ...

随机推荐

  1. 倍增 & Tarjan 求解LCA

    什么是LCA? 假设我们有一棵树: 1 / \ 2 3 / \ / 4 5 6 对于 \(2\) 和 \(6\) 的LCA,就是最近公共祖先,即为距离 \(2\) 和 \(6\) 最近的两个节点公有的 ...

  2. Java序列化:为何必须实现Serializable并显式指定serialVersionUID?

    结论先行 实现Serializable接口是Java对象序列化的基本前提,没有它JVM会直接拒绝序列化操作. 显式声明serialVersionUID能彻底掌控序列化版本兼容性,避免因类结构微小改动或 ...

  3. 制作netease-cloud-music-gtk的debian包

    要创建一个deb包,只需要有一个基于 debian 的操作系统即可.(不管你用的是什么 Linux 发行版,你可以使用虚拟机或者 systemd-nspawn 来创建构建 DEB 包的环境) 下载上游 ...

  4. 工具使用之“contains包含的使用总结”

    一.集合之间的包含 1.判断listOne是否全部包含listTow中的值 格式:CollectionUtils.containsAll(listOne, listTow) 或 listTow.con ...

  5. HeapSter部署

    pod资源需求,资源限制 Requests:需求,最低保障: Limits: 限制,硬限制: Limits >= request CPU: 1颗虚拟CPU=1000 毫核心 millicores ...

  6. vue3 基础-常用模板语法

    一个 vue 的单文件 SAP ( single page web application ) 即在一个 .vue 为后缀的文件中, 会包含3个部分. 模板: html 逻辑: javascript ...

  7. 将查询集SQL-存为物理 OR 临时表

    最近的BI项目, 就是会涉及大量的 sql, 后台处理也全是 sql 来拼接成一张物理宽表, 然后前台也是用 sql 来做各种图形骚操作. 尤其是后台处理部分, 大量的sql, 有点尴尬的事情是, s ...

  8. 关于思源笔记与docker的部分问题

    关于思源笔记 sevePath与思源 思源从版本1.9.8之后规定必须设置servePath绑定地址,即仅限指定地址访问. 比如,部署的时候设置的--servePath=127.0.0.1:6806, ...

  9. "NU1605: 错误形式的警告: 检测到包降级"的解决办法

    这两行的意思是需要我们升级Maui.Controls的版本在8.0.14,取高版本. 同理,再次进行: 最后:

  10. C#之可访问性约束(可访问性不一致)

    C# 语言中的有些构造要求某个类型至少与某个成员或其他类型具有同样的可访问性 (at least as accessible as).如果 T 的可访问域是 M 可访问域的超集,我们就说类型 T 至少 ...