如何基于JWT令牌过滤Spring AI MCP Server的工具列表?
解决Spring AI MCP Server令牌声明验证与工具权限控制问题
核心思路
由于McpAsyncServer的prepareRequestHandlers方法是框架核心初始化逻辑,直接重写受限,我们可以通过扩展Spring AI MCP的组件,绕过原方法的硬编码逻辑,实现自定义令牌校验与工具权限过滤。
具体实现步骤
1. 自定义工具权限管理器
创建组件负责解析令牌声明,返回当前用户允许使用的工具列表:
@Component public class ToolPermissionManager { private final JwtDecoder jwtDecoder; public ToolPermissionManager(JwtDecoder jwtDecoder) { this.jwtDecoder = jwtDecoder; } public List<String> getAuthorizedTools(HttpServletRequest request) { // 从请求头提取令牌 String token = request.getHeader("Authorization").replace("Bearer ", ""); Jwt jwt = jwtDecoder.decode(token); // 解析令牌中的权限声明,示例读取"allowed_tools"字段 List<String> allowedTools = jwt.getClaim("allowed_tools"); // 也可根据角色映射权限:比如admin拥有读写权限,普通用户仅读权限 // String role = jwt.getClaim("role"); // allowedTools = "admin".equals(role) ? Arrays.asList("read", "write") : Collections.singletonList("read"); return allowedTools; } }
2. 自定义MCP请求处理器包装器
创建包装类拦截原请求处理器,处理前校验权限并过滤工具:
@Component public class AuthorizedMcpRequestHandlerWrapper implements McpRequestHandler { private final McpRequestHandler delegate; private final ToolPermissionManager permissionManager; public AuthorizedMcpRequestHandlerWrapper(McpRequestHandler delegate, ToolPermissionManager permissionManager) { this.delegate = delegate; this.permissionManager = permissionManager; } @Override public Mono<McpResponse> handle(McpRequest request, ServerWebExchange exchange) { // 获取当前用户允许的工具列表 List<String> authorizedTools = permissionManager.getAuthorizedTools(exchange.getRequest()); // 过滤请求中的工具调用,仅保留用户有权限的工具 List<McpToolCall> filteredToolCalls = request.getToolCalls().stream() .filter(toolCall -> authorizedTools.contains(toolCall.getToolName())) .collect(Collectors.toList()); // 构建新的授权请求,替换过滤后的工具调用 McpRequest authorizedRequest = McpRequest.builder() .id(request.getId()) .toolCalls(filteredToolCalls) .metadata(request.getMetadata()) .build(); // 委托原处理器处理授权后的请求 return delegate.handle(authorizedRequest, exchange); } }
3. 替换默认MCP请求处理器
通过Spring的@Bean覆盖默认处理器,注入自定义包装器:
@Configuration public class McpServerConfig { @Bean public McpRequestHandler mcpRequestHandler(McpAsyncServer mcpAsyncServer, ToolPermissionManager permissionManager) { // 获取框架默认的请求处理器 McpRequestHandler originalHandler = mcpAsyncServer.prepareRequestHandlers(); // 返回包装后的授权处理器 return new AuthorizedMcpRequestHandlerWrapper(originalHandler, permissionManager); } }
4. 可选:新增用户授权工具列表端点
如果需要对外提供接口返回当前用户允许的工具列表,可新增REST端点:
@RestController @RequestMapping("/api/tools") public class ToolListController { private final ToolPermissionManager permissionManager; public ToolListController(ToolPermissionManager permissionManager) { this.permissionManager = permissionManager; } @GetMapping("/authorized") public List<String> getAuthorizedTools(HttpServletRequest request) { return permissionManager.getAuthorizedTools(request); } }
关键说明
- 该方案无需直接重写
McpAsyncServer#prepareRequestHandlers,而是利用Spring依赖注入特性替换默认处理器,实现权限控制。 - 令牌解析逻辑可根据实际认证方案调整(如OAuth2、自定义JWT等),核心是从请求中提取用户身份并映射到对应工具权限。
- 若需更细粒度控制(如工具参数校验),可在包装器中扩展对应逻辑。
内容的提问来源于stack exchange,提问作者Maxim
相关产品推荐
相关产品推荐

