You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.11 18:04:55