何时应该使用授权?
虽然 MCP servers 的授权是可选的,但在以下情况中强烈建议使用:- 服务器访问用户特定数据(邮件、文档、数据库)。
- 你需要审计谁执行了哪些操作。
- 服务器授权访问需要用户同意的 API。
- 你正在为具有严格访问控制的企业环境构建。
- 你希望按用户实现速率限制或使用量跟踪。
授权流程:分步说明
下面演示当 client 想连接受保护的 MCP server 时会发生什么:初始握手
当 MCP client 首次尝试连接时,server 会返回 这会告诉 client,该 MCP server 需要授权,并说明从哪里获取启动授权流程所需的信息。
401 Unauthorized,并告诉 client 在哪里查找授权信息。这些信息记录在 Protected Resource Metadata (PRM) document 中。该文档由 MCP server 托管,遵循可预测路径模式,并通过 WWW-Authenticate header 中的 resource_metadata 参数提供给 client。Protected Resource Metadata 发现
拿到 PRM 文档的 URI 指针后,client 会获取元数据,以了解授权服务器、支持的 scopes 和其他资源信息。数据通常封装在类似下面的 JSON blob 中。更完整的示例见 RFC 9728 Section 3.2。
授权服务器发现
接下来,client 会获取授权服务器元数据,以发现该授权服务器能做什么。如果 PRM 文档列出多个授权服务器,client 可以决定使用哪一个。选定授权服务器后,client 会构造标准元数据 URI,并向 OpenID Connect (OIDC) Discovery 或 OAuth 2.0 Auth Server Metadata 端点发起请求(取决于授权服务器支持情况),再获取另一组元数据属性,以了解完成授权流程所需的端点。
客户端注册
获取所有元数据后,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:用户授权
接下来,client 需要打开浏览器访问 access token 将被 client 用于向 MCP server 认证请求。该步骤遵循标准 OAuth 2.1 authorization code with PKCE 约定。
/authorize 端点,用户可在其中登录并授予所需权限。authorization server 随后会携带 authorization code 重定向回 client,client 再用该 code 换取 tokens:实现示例
为了开始实际实现,我们将使用托管在 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