OAuth保护的MCP服务器示例(Go语言)
使用Go语言编写的OAuth 2.1保护的模型上下文协议(MCP)服务器的示例实现。
特点/特性
- OAuth 2.0 受保护资源实施(方案/措施) RFC 9728(OAuth 2.0 受保护资源元数据)
- JWT访问令牌验证使用JWKS进行本地验证
- 可流式传输的HTTP传输可远程访问的MCP服务器
- 简单回声工具用于演示的基本MCP工具
- Keycloak 集成使用Keycloak 26.4作为授权服务器,支持动态客户端注册(DCR)
建筑学
OAuth 2.1 Flow (DCR, Authorization Code)
┌───────────────────────────────────────────────────────────┐
│ │
│ ▼
┌───┴─────────┐ HTTP + Bearer Token ┌─────────────┐ ┌───────────────┐
│ MCP Client │────────────────────────►│ MCP Server │ │ Keycloak │
│ (Inspector) │ │ (This repo) │ │ (AuthZ Server)│
└─────────────┘ └─────────────┘ └───────────────┘
│ │
│◄──────────────────┘
│ JWKS (RS256 Public Key)
│
▼
JWT Access Token Validation:
• Signature verification
• iss, exp, aud claims
• scope claim先决条件
- Go 1.25或更高版本
- Docker 和 Docker Compose(用于运行 Keycloak)
快速入门
1. 启动Keycloak
cd authz-server
docker-compose up -dKeycloak 将提供在 http://localhost (管理员/管理员)。
2. 配置 Keycloak
- 创建一个名为(新名称)的新领域
demo - 创建一个名为(此处应填写具体名称)的客户端范围
mcp:tools:
- 在令牌作用域中包含: On - 添加受众映射器: - 姓名: audience-config - 包含的自定义受众: http://localhost:8000
- 配置客户端策略:
- 删除默认的“受信任主机”策略 - 更新“允许的客户端范围”策略以包含 mcp:tools
- 创建一个测试用户
3. 运行MCP服务器
go run . \
-authz-server-url="http://localhost/realms/demo" \
-jwks-url="http://localhost/realms/demo/protocol/openid-connect/certs" \
-resource-url="http://localhost:8000"4. 使用MCP Inspector进行测试
跑 MCP 检查器 并连接到 http://localhost:8000。
MCP检查器将:
- 从(某处)获取受保护资源的元数据
http://localhost:8000/.well-known/oauth-protected-resource - 发现授权服务器元数据
- 使用动态客户端注册(DCR)注册为客户端
- 启动OAuth授权码流程
- 将您重定向到Keycloak登录页面
- 获取访问令牌并连接到MCP服务器
项目结构
.
├── authz-server/ # Keycloak setup
│ ├── docker-compose.yml
│ └── nginx.conf
├── main.go # MCP server implementation
├── oauth_middleware.go # OAuth middleware & JWT Access Token validation
└── README.md实施亮点
OAuth 2.0 受保护资源元数据
服务器在(某个位置)暴露元数据 /.well-known/oauth-protected-resource:
{
"resource": "http://localhost:8000",
"authorization_servers": ["http://localhost/realms/demo"],
"scopes_supported": ["mcp:tools"]
}JWT访问令牌验证
中间件进行验证:
- 签名使用来自授权服务器的JWKS(RS256)
- 标准索赔:
- iss (发行者):必须与授权服务器URL匹配 - exp (过期时间):令牌不得已过期 - aud (观众):必须包含此服务器的URL
- 自定义声明:
- scope必须包含 mcp:tools
MCP 工具
提供了一个简单的 echo 一个返回输入消息的工具。
配置选项
| 标志 | 描述 | 默认值 | |||
|---|---|---|---|---|---|
| 项目 | 描述 | 类型 | -authz-server-url | http://localhost/realms/demo | 授权服务器URL |
-jwks-url | http://localhost/realms/demo/protocol/openid-connect/certs | JWKS 端点 URL | |||
-resource-url | http://localhost:8000 | 此服务器的URL |
|
限制与注意事项
RFC 8707 支持 Keycloak 26.4 尚不支持RFC 8707(OAuth 2.0的资源指示符) mcp:tools 作为一种权宜之计,此实现方案使用了受众映射器(Audience Mapper)在 aud 范围以设定
声明;索赔;主张。
CORS 临时解决方案 由于一个Keycloak 26.4中的已知问题
nginx 被用作反向代理,为 DCR 端点添加 CORS 头信息。
RFC 8707:OAuth 2.0 的资源指示符
Keycloak(可译为“密钥圈”或保持原名,根据上下文决定是否需要翻译)
许可证
