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

mcp:tools scope。我们将用它来访问 MCP 服务器上的所有工具。

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

audience-config。为 Included Custom Audience 添加一个值,设为 http://localhost:3000。这将是我们测试服务器的 URI。
现在,导航到 Clients,然后是 Client registration,然后是 Trusted Hosts。禁用 Client URIs Must Match 设置,并添加你进行测试的主机。你可以在 Linux 或 macOS 上运行 ifconfig 命令,或在 Windows 上运行 ipconfig,来获取你当前的主机 IP。你可以通过查看 keycloak 日志中类似 Failed to verify remote host : 192.168.215.1 的一行,来看到你需要添加的 IP 地址。检查该 IP 地址与你的主机关联。取决于你的 docker 设置,这可能是一个桥接网络的地址。

- 前往 Clients。
- 点击 Create client。
- 给你的客户端一个唯一的 Client ID 并点击 Next。
- 启用 Client authentication 并点击 Next。
- 点击 Save。

MCP 服务器设置
我们现在将设置 MCP 服务器以使用本地运行的 Keycloak 授权服务器。取决于你的编程语言偏好,你可以使用受支持的 MCP SDK 之一。 为了测试目的,我们将创建一个极其简单的 MCP 服务器,它暴露两个工具——一个用于加法,另一个用于乘法。服务器将要求授权才能访问这些工具。- TypeScript
- Python
- C#
你可以在示例仓库中看到完整的 TypeScript 项目。在运行下面的代码之前,请确保你有一个包含以下内容的 当你运行服务器时,你可以通过提供 MCP 服务器端点,将它添加到你的 MCP 客户端(例如 Visual Studio Code)。有关在 TypeScript 中实现 MCP 服务器的更多细节,参见 TypeScript SDK 文档。
.env 文件:OAUTH_CLIENT_ID 和 OAUTH_CLIENT_SECRET 与我们先前创建的 MCP 服务器客户端关联。除了实现 MCP 授权规范之外,下面的服务器还通过 Keycloak 进行令牌自省,以确保它从客户端收到的令牌是有效的。它还实现了基本的日志记录,让你能够轻松诊断任何问题。测试 MCP 服务器
为了测试目的,我们将使用 Visual Studio Code,但任何支持 MCP 和新授权规范的客户端都适用。 按 Cmd + Shift + P 并选择 MCP: Add server…。选择 HTTP 并输入http://localhost:3000。给服务器一个在 Visual Studio Code 内部使用的唯一名称。在 mcp.json 中你现在应该看到一个像这样的条目:
mcp:tools scope。

mcp.json 中服务器条目的正上方看到列出的工具。

# 符号调用单个工具。

常见陷阱及如何避免它们
有关全面的安全指导,包括攻击向量、缓解策略和实现最佳实践,请务必通读安全最佳实践。下面点出几个关键问题。- 不要自己实现令牌校验或授权逻辑。对于令牌校验或授权决策之类的事情,使用现成的、经过充分测试的安全库。从头做一切意味着,除非你是安全专家,否则你更有可能实现得不正确。
- 使用短期访问令牌。取决于所使用的授权服务器,此设置可能是可自定义的。我们建议不要使用长期令牌——如果恶意行为者窃取了它们,他们将能够在更长时间内维持其访问。
- 始终校验令牌。你的服务器收到一个令牌,并不意味着该令牌是有效的,或者它是为你的服务器准备的。始终验证你的 MCP 服务器从客户端得到的内容符合所需的约束。
- 将令牌存储在安全、加密的存储中。在某些场景中,你可能需要在服务器端缓存令牌。如果是这种情况,确保存储具有正确的访问控制,且不能被有权访问你服务器的恶意方轻易外泄。你还应实现健壮的缓存驱逐策略,以确保你的 MCP 服务器不会重复使用过期或以其他方式无效的令牌。
- 在生产中强制 HTTPS。除了开发期间的
localhost,不要通过纯 HTTP 接受令牌或重定向回调。 - 最小权限 scope。不要使用一网打尽的 scope。在可能的情况下按工具或能力拆分访问,并在资源服务器上按路由/工具验证所需的 scope。
- 不要记录凭据。切勿记录
Authorizationheader、令牌、授权码或密钥。清洗查询字符串和 header。在结构化日志中编辑(redact)敏感字段。 - 分离应用凭据与资源服务器凭据。不要将你 MCP 服务器的 client secret 重用于最终用户流程。将所有密钥存储在一个正规的密钥管理器中,而不是源代码控制里。
- 返回正确的质询。在 401 时,包含带
Bearer、realm和resource_metadata的WWW-Authenticate,以便客户端可以发现如何认证。 - DCR(动态客户端注册)控制。如果启用,注意你组织特定的约束,例如受信任的主机、必需的审查和被审计的注册。未认证的 DCR 意味着任何人都可以在你的授权服务器上注册任何客户端。
- 多租户/realm 混淆。除非明确是多租户,否则锁定到单个 issuer/租户。拒绝来自其他 realm 的令牌,即使它们由同一个授权服务器签名。
- Audience/resource indicator 滥用。不要配置或接受通用的 audience(如
api)或不相关的 resource。要求 audience/resource 与你配置的服务器匹配。 - 错误细节泄露。向客户端返回通用消息,但在内部记录带相关性 ID 的详细原因,以便在不暴露内部机制的情况下帮助排查。
- 会话标识符加固。将
Mcp-Session-Id视为不受信任的输入;绝不将授权与它绑定。在认证变更时重新生成它,并在服务器端校验其生命周期。
相关标准和文档
MCP 授权建立在这些成熟的标准之上:- OAuth 2.1:核心授权框架
- RFC 8414:授权服务器元数据发现
- RFC 7591:动态客户端注册
- RFC 9728:受保护资源元数据
- RFC 8707:资源指示符(Resource Indicators)