跳到主内容

MCP 安全

部署 MCP 服务器就意味着暴露了一个 AI 客户端可以直接调用的工具接口。与人使用的传统 API 不同,MCP 服务器由智能体自主调用,而智能体可能拥有很大的权限。最重要的两个问题是:谁能调用哪些工具,以及 它们实际做了什么。

Casdoor 两方面都能解决。它既是把关访问的 OAuth 2.1 授权服务器,也是记录发生了什么的遥测后端。

访问控制​

MCP 使用 OAuth 2.1,授权服务器和资源服务器职责分明。 MCP 服务器(你的工具宿主)把认证完全交给外部提供商,自己从不管理用户,也不签发令牌。 Casdoor 就承担这个角色。

流程如何工作​

MCP 客户端第一次连接服务器时:

  1. 服务器返回 401 Unauthorized,WWW-Authenticate 请求头指向其受保护资源元数据接口。
  2. 客户端获取 /.well-known/oauth-protected-resource,发现是哪个授权服务器在保护这个资源。
  3. 如果客户端还没有凭据,会通过动态客户端注册(RFC 7591)在 Casdoor 注册自己。
  4. 客户端与 Casdoor 完成授权码 + PKCE 流程,获得带有用户同意的 scope 的访问令牌。
  5. 之后的请求带上 Authorization: Bearer <token>。 MCP 服务器在执行任何工具前,用 Casdoor 的 JWKS 接口校验 JWT。

MCP 服务器需要实现的很少:提供元数据文档、返回 401 质询、校验 JWT,以及按工具检查 scope。

基于 scope 的工具授权​

MCP 服务器中的每个工具都应该要求特定的 scope。 Casdoor 允许为每个应用定义自定义 scope,并在同意页上展示,让用户清楚自己授予了什么。

一个数据访问服务器的最小 scope 设计可能是这样:

作用域授予的访问
data:read只读查询工具
data:write写入类工具
管理员表结构和配置工具

令牌缺少所需 scope 时,工具处理程序返回 403:不是笼统的认证失败,而是有针对性的授权拒绝,错误信息中会写明缺少的 scope。

这样,只需要 data:read 的自动化任务可以拿到不含 data:write 的令牌,令牌即使泄露,影响范围也有限。

Casdoor 开箱即用提供的功能​

申请标准Casdoor 的实现
OAuth 2.1 授权服务器/login/oauth 接口
动态客户端注册/api/oauth/register 上的 RFC 7591
PKCE所有授权码流程强制使用
资源指示符(限定受众的令牌)RFC 8707
用于令牌校验的 JWKS/.well-known/jwks
同意页按应用配置(always / once / never)
自定义权限范围按应用定义,带显示名称和描述
多租户按组织划分的应用和用户

分步指南见 MCP 认证配置 和 集成示例。

审计与可观测性​

授权控制告诉你 应该 发生什么。可观测性告诉你 实际 发生了什么。

权限审计日志​

在你的组织上启用 Casdoor Permission Log 提供商。之后 Casdoor 会把每个非 GET 的 API 调用记录为一条权限条目:

[info]    sub=org/user  method=POST  url=/api/update-application  allowed=true
[warning] sub=org/user method=DELETE url=/api/delete-user allowed=false

这些条目显示在侧边栏的 Entries 中,按组织划分。被拒绝的请求显示为警告,策略违规一目了然。

用 OpenClaw 追踪智能体​

要更深入地了解 AI 智能体运行时在做什么,可以在应用旁部署 OpenClaw。 OpenClaw 会采集 LLM 调用、工具调用和智能体之间的流量,并通过 OTLP 把追踪数据发送给 Casdoor。 Casdoor 的追踪查看器把它们渲染成带时间和属性的 span 树。

权限日志覆盖 Casdoor API 层的授权决策,OpenClaw 追踪覆盖智能体内部行为和外部工具调用,两者配合使用。

威胁模型方面的考虑​

部署 MCP 服务器时,有几点值得注意:

scope 膨胀:AI 客户端有时会默认请求很宽的 scope。把 scope 定义得窄一些,对执行写入或删除的工具使用 "consent always"。要让用户知道自己授权了什么。

令牌有效期:MCP 客户端通常会缓存令牌直到过期。访问令牌有效期保持较短(15~60 分钟),对长时间运行的智能体签发刷新令牌。这样令牌泄露时的风险窗口更小。

客户端注册:动态客户端注册很方便,但也意味着任何能访问你 Casdoor 实例的人都能注册 OAuth 客户端。如果 MCP 服务器是内部使用的,考虑关闭 DCR,手动预先注册客户端。

受众校验:始终校验收到的令牌中的 aud 声明。为其他资源签发的有效 Casdoor 令牌,应该被你的 MCP 服务器拒绝。

延伸阅读​