热门搜索:和平精英 原神 街篮2 

您的位置:首页 > > 教程攻略 > ai资讯 >MCP最新企业级权限认证方案,STDIO/SSE不同实现详解!

MCP最新企业级权限认证方案,STDIO/SSE不同实现详解!

来源:互联网 更新时间:2026-06-28 14:17

在企业级MCP方案落地时,权限控制是个绕不开的话题。总不能谁都能访问MCP Server吧?或者更实际一点,不同用户进来,返回的数据也得不一样。这就涉及MCP Server的授权操作了。

MCP最新企业级权限认证方案,STDIO/SSE不同实现详解!

而MCP Server有两种传输方式,实现起来的路子也不太一样。

STDIO

这种方式在本地运行,它启动MCP Server的方式有点特别——直接把它当成子进程来跑。所谓的标准输入输出,说白了就是通过运行命令,往控制台写信息、读信息,靠这个来传输数据。

实际中,我们通常会配一段json,比如下面这个百度地图的MCP Server:

  • command和args这俩字段,就是指定要运行的命令和参数。
  • 其实env里面的BAIDU_MAP_API_KEY,才是做授权的那关键一笔。

如果你传的BAIDU_MAP_API_KEY不对,不好意思,权限就是没有。

"baidu-map": {
  "command": "cmd",
  "args": [
    "/c",
    "npx",
    "-y",
    "@baidumap/mcp-server-baidu-map"
  ],
  "env": {
    "BAIDU_MAP_API_KEY": "LEyBQxG9UzR9C1GZ6zDHsFDVKvBem2do"
  }
},

所以,STDIO做授权的方式相当直接:通过env(环境变量)搞定。具体步骤就三步:

  1. 服务端先发一个凭证给用户(可以是秘钥、token,这些都行)。这一步细节就不展开了,总归你得有个授权中心来发凭证。
  2. 然后MCP client通过env把凭证传进去。
  3. 最后MCP server从环境变量里读出来做鉴权。

在MCP Server端,用System.getenv()就能拿到env里的变量:

    @Tool(description = "获取用户余额")
    public String getScore() {
        String userName = System.getenv("API_KEY"); 
        // todo .. 鉴权处理
        return "未检索到当前用户"+userName;
    }

当然,也可以通过AOP的方式统一处理,更优雅一些。

不过,这里必须敲黑板:这种方式不支持动态鉴权。你不能指望在运行中随意更换环境变量。因为STDIO是本地运行,MCP Server是作为子进程启动的。如果有多个用户要动态切换凭证,大家就会一起抢共享的环境变量,最后只能存一个。除非你给每个用户单独开一个STDIO MCP Server,但这显然不现实,性能根本扛不住。所以,如果要搞多用户动态切换授权,还是得看SSE。

SSE

说明

如果你想把MCP服务器开放给外部使用,那就要暴露标准的HTTP接口。在私有场景下,可能不需要太严格的身份认证,但在企业级部署中,安全权限就变得至关重要了。2025年3月发布的最新MCP规范,干脆引入了安全基础,直接用上了广泛使用的OAuth2框架。

OAuth2的具体细节这里就不展开了,但简单回顾一下很有必要。

在规范的草案中,MCP服务器既是资源服务器,也是授权服务器。

  • 作为资源服务器

    ,MCP负责检查每个请求中的Authorization请求头。这个请求头里必须包含OAuth2的access_token(令牌),它相当于客户端的"通行证"。这个令牌通常是JWT(JSON Web Token),也可能是一个不可读的随机字符串。如果令牌缺失或无效(比如无法解析、已过期、不是发给本服务器的等等),请求会被直接拒绝。正常的调用示例如下:
curl https://mcp.example.com/sse -H "Authorization: Bearer <有效的 access token>"
  • 作为授权服务器

    ,MCP还需要有能力安全地为客户端签发access_token。在发放令牌前,它会校验客户端的凭据,有时还要校验访问用户的身份。授权服务器决定令牌的有效期、权限范围、目标受众等特性。

借助Spring Security和Spring Authorization Server,可以很方便地给现有的Spring MCP服务器加上这两大安全能力。

给Spring MCP服务器加上OAuth2支持

我们用官方例子仓库里的"天气"MCP工具来演示。核心目标就是让服务器端既能签发令牌,又能校验令牌。

首先,在pom.xml里加上必要的依赖:


  org.springframework.boot
  spring-boot-starter-oauth2-resource-server


  org.springframework.boot
  spring-boot-starter-oauth2-authorization-server

接着,在application.properties里配置一个简易的OAuth2客户端信息,方便后面请求令牌:

spring.security.oauth2.authorizationserver.client.oidc-client.registration.client-id=xushu
spring.security.oauth2.authorizationserver.client.oidc-client.registration.client-secret={noop}xushu666
spring.security.oauth2.authorizationserver.client.oidc-client.registration.client-authentication-methods=client_secret_basic
spring.security.oauth2.authorizationserver.client.oidc-client.registration.authorization-grant-types=client_credentials

这么定义好之后,你就可以直接通过POST请求跟授权服务器交互了,不需要浏览器,用配置好的/secret作为固定凭据。最后一步是开启授权服务器和资源服务器的功能。通常要新增一个安全配置类,比如SecurityConfiguration

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();
    }
}

这个过滤链干了几件事:

  • 要求所有请求都经过身份认证。也就是说,访问MCP的接口,必须带上access_token。
  • 同时启用了授权服务器和资源服务器两大能力。
  • 关闭了CSRF(跨站请求伪造防护),因为MCP不是给浏览器直接用的,这部分没必要开。
  • 打开了CORS(跨域资源共享),方便用MCP inspector测试。

配置完以后,只有带access_token的访问才会被接受,否则直接返回401未授权错误:

curl http://localhost:8080/sse --fail-with-body
# 返回:
# curl: (22) The requested URL returned error: 401

要使用MCP服务器,先获取一个access_token。可以通过client_credentials授权方式(适用于机器到机器、服务账号的场景):

curl -XPOST http://localhost:8080/oauth2/token --data grant_type=client_credentials --user xushu:xushu666
# 返回:
# {"access_token":"","token_type":"Bearer","expires_in":299}

把返回的access_token记下来(它一般以"ey"开头),之后就可以用它来正常请求服务器了:

curl http://localhost:8080/sse -H"Authorization: Bearer YOUR_ACCESS_TOKEN"
# 服务器响应内容

你还可以直接在MCP inspector工具里用这个access_token。从菜单的Authentication > Bearer处粘贴令牌,然后连接即可。

为MCP Client设置请求头

目前,MCP的Ja va SDK还没有提供直接的API来调用。研究过源码后,发现只能通过两种方式实现:

重写源码

一种办法是把MCP的SSE方式的Ja va SDK源码整个重写一遍。工作量确实不小,而且可以预期的是,过不了多久Spring AI和MCP协议都会更新这块。所以主要看你的紧急程度。如果更看重整体扩展性和维护性,整体重写一遍也是值得考虑的。

这里提供一个重写思路:

重写McpSseClientProperties

在MCPSse客户端的属性配置里新增请求头字段:

package org.springframework.ai.autoconfigure.mcp.client.properties;

@ConfigurationProperties("spring.ai.mcp.client.sse")
public class McpSseClientProperties {
    public static final String CONFIG_PREFIX = "spring.ai.mcp.client.sse";
    private final Map connections = new HashMap();
    
    private final Map headersMap = new HashMap<>();
    private String defaultHeaderName;
    private String defaultHeaderValue;
    private boolean enableCompression = false;
    private int connectionTimeout = 5000;

    // ... 省略 getter/setter ...
}

重写SseWebFluxTransportAutoConfiguration

自动装配时添加请求头配置信息:

package org.springframework.ai.autoconfigure.mcp.client;

@AutoConfiguration
@ConditionalOnClass({WebFluxSseClientTransport.class})
@EnableConfigurationProperties({McpSseClientProperties.class, McpClientCommonProperties.class})
@ConditionalOnProperty(
        prefix = "spring.ai.mcp.client",
        name = {"enabled"},
        ha vingValue = "true",
        matchIfMissing = true
)
public class SseWebFluxTransportAutoConfiguration {
    // ... 核心逻辑,在构建WebClient时注入headersMap ...
}

设置WebClientCustomizer

在用Spring-ai-M8版本的时候,发现它提供了WebClientCustomizer进行扩展。可以尝试这种方式:

  1. 先根据用户凭证进行授权:
curl -XPOST http://localhost:8080/oauth2/token --data grant_type=client_credentials --user xushu:xushu666  
  1. 然后根据授权后得到的token去请求:
@Bean
public WebClientCustomizer webClientCustomizer() {
    return (builder) -> {
        builder.defaultHeader("Authorization","Bearer eyJraWQiOiIzYmMzMDRmZC02NzcyLTRkYTItODJiMy1hNTEwNGExMDBjNTYiLCJhbGciOiJSUzI1NiJ9...");
    };
}

这里需要特别说明一下:SSE是支持动态切换token的,因为每个请求都是一个全新的HTTP请求,不会出现多线程争抢的情况。如果需要动态授权,每次可以重新执行 curl -XPOST http://localhost:8080/oauth2/token --data grant_type=client_credentials --user xushu:xushu666 来获取新的令牌。

AI自动绘画大师
AI自动绘画大师

类型:益智休闲

大小:5.72MB

语言:简体中文

平台:互联网

游戏下载

热门手游

手机号码测吉凶
本站所有软件,都由网友上传,如有侵犯你的版权,请发邮件haolingcc@hotmail.com 联系删除。 版权所有 Copyright@2012-2013 haoling.cc