何时应该使用授权?
虽然 MCP servers 的授权是可选的,但在以下情况中强烈建议使用:- 服务器访问用户特定数据(邮件、文档、数据库)。
- 你需要审计谁执行了哪些操作。
- 服务器授权访问需要用户同意的 API。
- 你正在为具有严格访问控制的企业环境构建。
- 你希望按用户实现速率限制或使用量跟踪。
授权流程:分步说明
下面演示当 client 想连接受保护的 MCP server 时会发生什么:1
初始握手
当 MCP client 首次尝试连接时,server 会返回 这会告诉 client,该 MCP server 需要授权,并说明从哪里获取启动授权流程所需的信息。
401 Unauthorized,并告诉 client 在哪里查找授权信息。这些信息记录在 Protected Resource Metadata (PRM) document 中。该文档由 MCP server 托管,遵循可预测路径模式,并通过 WWW-Authenticate header 中的 resource_metadata 参数提供给 client。2
Protected Resource Metadata 发现
拿到 PRM 文档的 URI 指针后,client 会获取元数据,以了解授权服务器、支持的 scopes 和其他资源信息。数据通常封装在类似下面的 JSON blob 中。更完整的示例见 RFC 9728 Section 3.2。
3
授权服务器发现
接下来,client 会获取授权服务器元数据,以发现该授权服务器能做什么。如果 PRM 文档列出多个授权服务器,client 可以决定使用哪一个。选定授权服务器后,client 会构造标准元数据 URI,并向 OpenID Connect (OIDC) Discovery 或 OAuth 2.0 Auth Server Metadata 端点发起请求(取决于授权服务器支持情况),再获取另一组元数据属性,以了解完成授权流程所需的端点。
4
客户端注册
获取所有元数据后,client 需要确保自己已在授权服务器注册。这可以通过两种方式完成。首先,client 可以在给定 authorization server 中预注册。在这种情况下,它可以内嵌 client 注册信息,并用这些信息完成授权流程。或者,client 可以使用 Dynamic Client Registration (DCR) 向 authorization server 动态注册自身。后一种场景要求 authorization server 支持 DCR。如果 authorization server 支持 DCR,client 会将自身信息发送到 如果注册成功,authorization server 会返回包含 client 注册信息的 JSON blob。
registration_endpoint:5
用户授权
接下来,client 需要打开浏览器访问 access token 将被 client 用于向 MCP server 认证请求。该步骤遵循标准 OAuth 2.1 authorization code with PKCE 约定。
/authorize 端点,用户可在其中登录并授予所需权限。authorization server 随后会携带 authorization code 重定向回 client,client 再用该 code 换取 tokens:6
发起已认证请求
最后,client 可以在 MCP server 需要校验 token;如果 token 有效且具备所需权限,则处理该请求。
Authorization header 中携带 access token,向你的 MCP server 发起请求:实现示例
为了开始实际实现,我们将使用托管在 Docker container 中的 Keycloak authorization server。Keycloak 是开源 authorization server,可以轻松在本地部署用于测试和实验。 请确保已下载并安装 Docker Desktop。我们需要用它在开发机器上部署 Keycloak。Keycloak 设置
在终端应用中运行以下命令启动 Keycloak container:8080 端口,并带有用户名为 admin、密码为 admin 的用户。
你可以在浏览器中通过 http://localhost:8080 访问 Keycloak authorization server。

mcp:tools scope。我们会用它访问 MCP server 上的所有 tools。

mcp:tools client scope,点击 Mappers,再点击 Configure a new mapper。选择 Audience。

audience-config。为 Included Custom Audience 添加值 http://localhost:3000。这将作为测试 server 的 URI。
现在,进入 Clients,然后进入 Client registration,再进入 Trusted Hosts。禁用 Client URIs Must Match 设置,并添加你用于测试的 hosts。你可以在 Linux 或 macOS 上运行 ifconfig,或在 Windows 上运行 ipconfig 来获取当前 host IP。也可以查看 Keycloak 日志中类似 Failed to verify remote host : 192.168.215.1 的行,找到需要添加的 IP 地址。请确认该 IP 地址与你的 host 关联。根据你的 Docker 设置,它可能来自 bridge network。

- 进入 Clients。
- 点击 Create client。
- 为 client 设置唯一的 Client ID,然后点击 Next。
- 启用 Client authentication,然后点击 Next。
- 点击 Save。

MCP Server 设置
现在将 MCP server 设置为使用本地运行的 Keycloak authorization server。你可以根据偏好的编程语言,选择一个受支持的 MCP SDKs。 出于测试目的,我们会创建一个极其简单的 MCP server,暴露两个 tools:一个用于加法,另一个用于乘法。访问这些 tools 需要授权。- TypeScript
- Python
- C#
完整 TypeScript 项目见示例仓库。运行下面的代码前,请确保有一个包含以下内容的 运行 server 后,可以通过提供 MCP server endpoint,将它添加到 MCP client(例如 Visual Studio Code)中。关于使用 TypeScript 实现 MCP servers 的更多细节,请参考 TypeScript SDK documentation。
.env 文件:OAUTH_CLIENT_ID 和 OAUTH_CLIENT_SECRET 对应前面创建的 MCP server client。除实现 MCP 授权规范外,下面的 server 还会通过 Keycloak 执行 token introspection,确保它从 client 收到的 token 有效。它还实现了基础日志,便于诊断问题。测试 MCP Server
为了测试,我们会使用 Visual Studio Code,但任何支持 MCP 和新版授权规范的 client 都可以。 按 Cmd + Shift + P,选择 MCP: Add server…。选择 HTTP 并输入http://localhost:3000。为 server 指定一个在 Visual Studio Code 中使用的唯一名称。现在你应该能在 mcp.json 中看到类似条目:
mcp:tools scope。

mcp.json 中 server 条目上方。

# 符号调用单个 tools。

常见问题和避免方法
关于攻击向量、缓解策略和实现最佳实践等完整安全指导,请务必阅读 Security Best Practices。下面列出几个关键问题。- 不要自行实现 token 校验或授权逻辑。对于 token 校验或授权决策等事项,请使用现成、经过充分测试且安全的库。除非你是安全专家,否则从零实现更容易出错。
- 使用短生命周期 access tokens。根据所用 authorization server,这项设置可能可以自定义。建议不要使用长期 tokens;如果恶意行为者窃取它们,就能维持更长时间的访问权限。
- 始终校验 tokens。server 收到 token 并不意味着该 token 有效,也不意味着它是发给你的 server 的。始终验证 MCP server 从 client 收到的内容是否满足所需约束。
- 将 tokens 存储在安全、加密的存储中。某些场景下,你可能需要在服务器端缓存 tokens。如果这样做,请确保存储具备正确访问控制,且不能被有权访问 server 的恶意方轻易外泄。还应实现健壮的缓存驱逐策略,确保 MCP server 不会复用过期或无效 tokens。
- 生产环境强制 HTTPS。开发期间除
localhost外,不要通过明文 HTTP 接受 tokens 或 redirect callbacks。 - 最小权限 scopes。不要使用 catch-all scopes。尽可能按 tool 或 capability 拆分访问权限,并在 resource server 上按 route/tool 校验所需 scopes。
- 不要记录凭据。绝不要记录
Authorizationheaders、tokens、codes 或 secrets。清理 query strings 和 headers。在结构化日志中遮蔽敏感字段。 - 区分 app 与 resource server 凭据。不要将 MCP server 的 client secret 复用于最终用户 flows。将所有 secrets 存储在合适的 secret manager 中,不要放在源代码控制中。
- 返回正确 challenges。401 时包含带
Bearer、realm和resource_metadata的WWW-Authenticate,让 clients 能发现如何认证。 - DCR (Dynamic Client Registration) 控制。如果启用 DCR,请注意组织特定约束,例如 trusted hosts、必要审查和可审计注册。未认证 DCR 意味着任何人都可以在你的 authorization server 中注册任何 client。
- 多租户/realm 混淆。除非明确支持多租户,否则固定到单个 issuer/tenant。即使由同一个 authorization server 签名,也要拒绝其他 realms 的 tokens。
- Audience/resource indicator 误用。不要配置或接受通用 audiences(例如
api)或无关 resources。要求 audience/resource 与已配置 server 匹配。 - 错误详情泄露。向 clients 返回通用消息,但在内部日志中用 correlation IDs 记录详细原因,以便排障且不暴露内部细节。
- Session identifier 加固。将
Mcp-Session-Id视为不可信输入;绝不要将授权绑定到它。认证变化时重新生成,并在服务器端校验生命周期。
相关标准和文档
MCP 授权建立在以下成熟标准之上:- OAuth 2.1:核心授权框架
- RFC 8414:Authorization Server Metadata 发现
- RFC 7591:Dynamic Client Registration
- RFC 9728:Protected Resource Metadata
- RFC 8707:Resource Indicators