关于 MCP + OAuth2.1 + AWS Cognito Example
这是一个示例项目,展示如何使用 Node.js 和 Express.js 通过 OAuth 2.1 保护 MCP 服务。示例使用 AWS Cognito 作为授权服务器,但实现与提供商无关。它面向希望理解 MCP 授权规范的开发者。
主要功能
- 01MCP 服务作为资源服务器(RS)运行
- 02基于 PKCE 的 OAuth 2.1 授权码流程
- 03受保护资源元数据(PRM)发现
- 04动态客户端注册(DCR)支持
- 05客户端 ID 元数据文档(CIMD)支持
适用场景
- 01学习 MCP 授权规范的实现方式
- 02为 MCP 服务接入 AWS Cognito 等授权服务器
- 03对比 DCR 与 CIMD 两种客户端注册方式
MCP 相关
该项目是 MCP 服务的授权示例,服务端通过 /.well-known/oauth-protected-resource 提供 PRM 元数据,并在请求时校验访问令牌。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
MCP + OAuth2.1 + AWS Cognito 示例
概述
本仓库演示如何使用 OAuth 2.1 授权流程保护 Model Context Protocol(MCP)服务,整个实现均基于 Node.js 和 Express.js。虽然此示例使用 AWS Cognito 作为后端授权服务,但该实现与提供商无关,可与任何符合 OAuth 2.1 标准的授权服务配合使用。
本项目基于 MCP 授权规范(版本 2025-11-25),展示了:
- 作为 资源服务(RS)的 MCP 服务,提供通用 OAuth 端点
- 与提供商无关的 OAuth 2.1 实现(示例使用 AWS Cognito)
- 使用 PKCE 和 RFC 8707 资源指示器的 OAuth 2.1 授权码流程
- 受保护资源元数据(PRM)文档发现
- 完全动态的授权服务元数据发现
- 支持动态客户端注册(DCR)
- 支持客户端 ID 元数据文档(CIMD)
- MCP 2025-11-25 规范新增的安全功能
- 三种客户端实现:
- 使用预配置凭据的静态客户端
- 采用动态注册(DCR)的自动发现客户端
- 使用客户端 ID 元数据文档(CIMD)的元数据客户端
与提供商无关的设计
此实现遵循 OAuth 2.1 标准,确保与任何符合标准的授权服务兼容:
- MCP 服务:公开标准 OAuth 元数据端点,并代理到后端授权服务
- 客户端:动态发现授权服务,不依赖硬编码的特定提供商逻辑
- 令牌验证:使用从授权服务元数据中发现的 JWKS URI 和签发者信息
- 灵活的后端:示例使用 Cognito,但可替换为任何 OAuth 2.1 服务
了解新版 MCP 授权规范
新版 MCP 授权规范将资源服务器与授权服务器清晰地分离开来,因此更容易与 AWS Cognito、Okta、Auth0 等现有身份提供商集成。
规范的关键组成部分:
-
**受保护资源元数据(PRM)**文档
- MCP 服务在
/.well-known/oauth-protected-resource提供此文档 - 包含授权服务器、支持的范围等信息
- 遵循 RFC9728(OAuth 2.0 受保护资源元数据)
- MCP 服务在
-
发现流程
- 客户端收到 401 Unauthorized 响应时,WWW-Authenticate 标头中会包含指向 PRM 文档的链接
- 客户端获取 PRM 文档,以发现授权服务器 URL
- 客户端从发现的 URL 动态获取授权服务器元数据(无需硬编码端点)
-
OAuth 2.1 授权
- 使用 PKCE 的授权码流程
- 在已验证身份的请求中使用 Bearer 令牌
- 使用发现的 JWKS URI 和发行者信息动态验证令牌
-
客户端注册优先级(MCP 2025-11-25)
- 预注册客户端凭据(如果该服务有可用凭据)
- 客户端 ID 元数据文档(如果授权服务器公布了
client_id_metadata_document_supported: true) - 动态客户端注册(RFC7591 后备方案)
- 提示用户手动配置(最后手段)
-
动态客户端注册(DCR)
- 允许客户端自动向新的 MCP 服务注册
- 无需手动注册客户端
- 遵循 RFC7591(OAuth 2.0 动态客户端注册协议)
-
客户端 ID 元数据文档(CIMD)
- 客户端通过 HTTPS URL 发布其 OAuth 元数据
- 该 URL 本身即为
client_id - 授权服务器获取并验证元数据文档
- 无需预注册或数据库存储
- 遵循 draft-ietf-oauth-client-id-metadata-document
此实现展示了如何以不依赖特定提供商的方式应用这些概念。示例使用 AWS Cognito,通过 API Gateway 端点和 Lambda 函数实现自定义动态客户端注册,但核心 OAuth 流程适用于任何兼容的授权服务器。
架构
Client → MCP Server → Authorization Server (e.g., AWS Cognito)
(Resource Server) (OAuth 2.1 Provider)
- 客户端发送不带令牌的请求。
- MCP 服务返回 401 Unauthorized 响应,并在 WWW-Authenticate 标头中提供指向 PRM 元数据的链接。
- 客户端获取 PRM,并动态发现授权服务器 URL。
- 客户端获取授权服务器元数据,并执行 OAuth 2.1 授权码流程(使用 PKCE)。
- 客户端获取访问令牌,并重试向 MCP 服务发送请求。
- MCP 服务使用动态发现的 JWKS 验证令牌,并授予对受保护资源的访问权限。
详细概述请参阅架构概述。
图示:
动态客户端注册(DCR)
此实现支持 OAuth 2.1 动态客户端注册,允许客户端:
- 动态发现 MCP 服务和授权端点
- 向授权服务器注册自身
- 获取 OAuth 流程所需的凭据
DCR 流程如下:
- 客户端发现 MCP 服务的受保护资源元数据
- 客户端发现授权服务器(Cognito)
- 客户端在 API Gateway 的 DCR 端点注册
- 注册会创建 Cognito 应用客户端并返回凭据
- 客户端使用这些凭据执行标准 OAuth 2.1 流程
实现说明: AWS Cognito 原生不支持 OAuth 2.0 DCR(RFC7591)中规定的动态客户端注册。本实现通过以下方式弥补这一不足:
- 使用 API Gateway 端点提供 DCR API 接口
- 使用 Lambda 函数以编程方式创建 Cognito 应用客户端
- 使用 DynamoDB 存储注册数据
这种方式既能遵循 MCP 规范对 DCR 的建议,也能利用 AWS Cognito 提供可靠的身份验证和授权。
安全说明:本实现使用匿名 DCR,不进行额外身份验证。在生产环境中,请考虑添加:
- 对注册请求进行速率限制
- 客户端身份验证(mTLS、初始访问令牌)
- 新客户端审批工作流
- 限制动态注册客户端的访问范围
请参阅我们的 DCR 安全建议,以增强注册流程的安全性。
客户端 ID 元数据文档(CIMD)
MCP Authorization Specification(2025-11-25)引入了客户端 ID 元数据文档,作为推荐的客户端注册方式。CIMD 允许客户端使用 HTTPS URL 作为其 client_id,该 URL 指向一个描述客户端 OAuth 元数据的 JSON 文档。
CIMD 的工作方式
- 客户端在某个 URL 发布元数据文档(例如,
http://localhost:3003/client-metadata.json) - 在 OAuth 授权期间,客户端使用此 URL 作为其
client_id - 授权服务器从该 URL 获取元数据文档
- 服务器验证文档结构和重定向 URI
- 客户端继续执行标准 OAuth 2.1 流程
CIMD 元数据文档示例
{
"client_id": "http://localhost:3003/client-metadata.json",
"redirect_uris": ["http://localhost:3003/callback"],
"client_name": "MCP CIMD Demo Client",
"grant_types": ["authorization_code"],
"response_types": ["code"],
"token_endpoint_auth_method": "none"
}
CIMD 授权代理
AWS Cognito 原生不支持客户端 ID 元数据文档,与其原生不支持 DCR 一样。本实现通过 MCP 服务的授权代理透明地支持 CIMD:
- MCP 服务在授权服务器元数据中公布
client_id_metadata_document_supported: true - MCP 服务在元数据中将
authorization_endpoint和token_endpoint覆盖为指向自身 - 当客户端提供基于 URL 的
client_id时:- 代理获取并验证客户端的元数据文档
- 通过现有 DCR 基础设施透明地创建 Cognito 应用客户端
- 使用映射后的凭据将请求转发至 Cognito
- 当客户端提供标准
client_id(预注册或通过 DCR 注册)时:请求将原样传递给 Cognito
metadata-client 无需为 CIMD 编写任何自定义代码——它只需将元数据 URL 用作 client_id,并使用标准 OAuth 端点,与任何符合规范的客户端一样。所有桥接工作均由服务端处理。
CIMD 安全性
授权代理包含:
- SSRF 防护(阻止私有 IP 地址范围,并在生产环境中强制使用 HTTPS)
- 严格的
client_id验证(必须与元数据 URL 完全匹配) - 重定向 URI 验证
- 响应大小限制(64KB)和获取超时(5s)
- 内存缓存,以避免重复获取
注意:在开发环境中,允许使用 http://localhost URL。生产部署必须使用 HTTPS。
快速开始
前置条件
- 已安装 Node.js 18+
- 可访问以下服务的 AWS 测试账户:
- 用于授权服务器的 Cognito(1 个用户池、2 个应用客户端)
- 用于 DCR 和 CIMD 桥接的 API Gateway / Lambda / DynamoDB(2 个资源、2 个函数、1 个表)
- 用于部署的 CloudFormation(1 个堆栈)
- 具备 OAuth 2.1 流程的基础知识
设置
-
克隆仓库
git clone https://github.com/empires-security/mcp-oauth2-aws-cognito.git cd mcp-oauth2-aws-cognito -
为客户端和服务安装依赖项
npm run install:all -
部署 AWS 资源
npm run deploy -
检查以下位置生成的
.env文件:src/client/.envsrc/auto-client/.envsrc/metadata-client/.envsrc/mcp-server/.env- 与
.env.example文件进行比较 - 如有需要,手动验证或更新 CLIENT_SECRET
运行应用程序
-
启动所有服务(服务端 + 3 个客户端)
npm run dev -
访问 http://localhost:3000,测试**预注册客户端** OAuth 流程
-
注册新用户
- 点击“Log in”按钮
- 在 Cognito 托管式 UI 中选择“Sign up”
- 创建新用户账户
- 输入发送到你邮箱的确认码,验证账户
- 验证成功后,你将被重定向回应用程序
-
点击“Fetch MCP Data”按钮,向 MCP 服务发送经过身份验证的请求
-
访问 http://localhost:3002,测试**DCR 流程**(带有动态客户端注册功能的自动发现客户端)
-
访问 http://localhost:3003,测试**CIMD 流程**(客户端 ID 元数据文档客户端)
清理
- 清理 AWS 资源
npm run cleanup
详细设置说明请参阅设置指南。
贡献
欢迎贡献!请随时提交 Pull Request。
- Fork 此仓库
- 创建功能分支(
git checkout -b feature/amazing-feature) - 提交更改(
git commit -m 'Add some amazing feature') - 推送到分支(
git push origin feature/amazing-feature) - 创建 Pull Request
参考资料
- Model Context Protocol 授权规范(2025-11-25)
- OAuth 2.1 草案
- OAuth 2.0 受保护资源元数据(RFC 9728)
- OAuth 2.0 动态客户端注册协议(RFC 7591)
- OAuth 客户端 ID 元数据文档(草案)
- AWS Cognito 开发人员指南
许可证
本项目采用 MIT 许可证授权,详情请参阅 LICENSE 文件。
作者
- Empires Security Labs 🚀
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。