返回市场
MCP授权网关

MCP授权网关

作者:akshay59953 星标更新:2025-07-24

项目介绍

MCP OAuth Gateway

一个OAuth 2.1授权服务器,为模型上下文协议(MCP)服务提供透明的身份验证和授权。

功能

  • 透明的MCP访问:用户通过简单的URL访问MCP服务,无需手动设置OAuth。
  • 单一OAuth提供商:使用一个OAuth提供商为所有服务提供支持(如Google、GitHub、Okta或自定义)。
  • 完整的MCP合规性:实现完整的MCP授权规范,采用OAuth 2.1。
  • 动态客户端注册:根据RFC 7591自动注册客户端。
  • 用户上下文注入:无缝地向后端MCP服务传递用户上下文头信息。
  • 资源特定令牌:RFC 8707受众绑定防止令牌滥用。
  • 可配置存储:内存(开发)、Redis(生产)、Vault(企业)后端。
  • 生产就绪:全面测试、Docker支持、可扩展架构。

📖 查看详细架构 | 📚 开发者指南

使用Docker快速开始(推荐)

预构建镜像

使用GitHub容器注册表中的预构建Docker镜像:

# 使用内存存储(开发)
docker run -p 8080:8080 \
  -v $(pwd)/config.yaml:/app/config.yaml \
  -e GOOGLE_CLIENT_ID="your-google-client-id" \
  -e GOOGLE_CLIENT_SECRET="your-google-client-secret" \
  ghcr.io/akshay5995/mcp-oauth-gateway:latest

Docker Compose(全栈)

# 复制环境模板
cp .env.example .env
# 编辑.env文件,添加您的OAuth凭证

# 启动所有服务(网关 + Redis + 示例计算器)
docker-compose up -d

# 测试设置
curl http://localhost:8080/health
curl http://localhost:8080/calculator/mcp  # 应返回401并带有OAuth信息

本地开发设置

1. 安装依赖

pip install -r requirements.txt

# 可选:对于现代库的Redis存储后端
pip install -r requirements-redis.txt

2. 配置OAuth提供商

重要:每个网关实例只能配置一个OAuth提供商。

设置Google OAuth环境变量:

export GOOGLE_CLIENT_ID="your-google-client-id"
export GOOGLE_CLIENT_SECRET="your-google-client-secret"

📚 其他提供商:参见配置指南了解GitHub、Okta和自定义OAuth提供商的配置方法。

3. 创建基本配置

创建一个config.yaml文件:

# 网关设置
host: "localhost"
port: 8080
issuer: "http://localhost:8080"
session_secret: "your-dev-secret-change-in-production"
debug: true

# OAuth提供商
oauth_providers:
  google:
    client_id: "${GOOGLE_CLIENT_ID}"
    client_secret: "${GOOGLE_CLIENT_SECRET}"
    scopes: ["openid", "email", "profile"]

# 示例服务(替换为您自己的MCP服务)
mcp_services:
  calculator:
    name: "计算器服务"
    url: "http://localhost:3001"
    oauth_provider: "google"
    auth_required: true
    scopes: ["read", "calculate"]

4. 运行网关

python -m src.gateway --config config.yaml --debug

5. 测试设置

访问您的服务以验证其是否正常工作:

curl http://localhost:8080/calculator/mcp
# 应返回401并带有OAuth认证信息

6. 添加您的服务

config.yaml中替换示例服务为您实际的MCP服务。所有服务必须使用相同的OAuth提供商。

📚 完整配置指南 - 详细的配置选项

MCP客户端集成

1. 发现

MCP客户端首先访问服务端点:

GET /calculator/mcp HTTP/1.1
Host: localhost:8080

网关响应OAuth元数据:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="http://localhost:8080/.well-known/oauth-protected-resource"

2. 元数据检索

客户端获取OAuth元数据:

curl http://localhost:8080/.well-known/oauth-authorization-server
curl http://localhost:8080/.well-known/oauth-protected-resource

3. 动态客户端注册

客户端自动注册:

curl -X POST http://localhost:8080/oauth/register \
  -d "client_name=我的MCP客户端" \
  -d "redirect_uris=http://localhost:8080/callback"

4. 授权流程

客户端遵循标准的OAuth 2.1流程,包括PKCE:

  1. 带有资源参数的授权请求
  2. 用户通过配置的提供商进行身份验证
  3. 用授权码交换访问令牌
  4. 认证后的MCP请求

配置

网关设置

host: "0.0.0.0"
port: 8080
issuer: "https://mcp-gateway.example.com"
session_secret: "production-secret-key"
debug: false

CORS配置

为Web客户端配置跨源资源共享(CORS):

cors:
  allow_origins: ["*"]         # 允许的来源(生产环境中使用具体域名)
  allow_credentials: true      # 在CORS请求中允许凭证
  allow_methods:               # 允许的HTTP方法
    - "GET"
    - "POST"
    - "PUT"
    - "DELETE"
    - "OPTIONS"
  allow_headers: ["*"]         # 允许的头信息(生产环境中使用具体头信息)

对于生产部署,限制CORS设置:

cors:
  allow_origins: 
    - "https://myapp.example.com"
    - "https://dashboard.example.com"
  allow_credentials: true
  allow_methods: ["GET", "POST", "OPTIONS"]
  allow_headers: 
    - "Authorization"
    - "Content-Type"
    - "MCP-Protocol-Version"

OAuth提供商配置

重要:由于OAuth 2.1资源参数的限制,每个网关实例只能配置一个OAuth提供商。

oauth_providers:
  google:
    client_id: "${GOOGLE_CLIENT_ID}"
    client_secret: "${GOOGLE_CLIENT_SECRET}"
    scopes: ["openid", "email", "profile"]

📚 替代提供商:参见配置指南了解GitHub、Okta和自定义OAuth提供商的配置示例。

MCP服务

mcp_services:
  calculator:
    name: "计算器服务"
    url: "http://calculator:3001"
    oauth_provider: "google"  # 必须与配置的OAuth提供商匹配
    auth_required: true
    scopes: ["read", "calculate"]
    timeout: 30000
  
  # 所有认证服务必须使用相同的OAuth提供商
  weather:
    name: "天气服务"
    url: "http://weather:3002"
    oauth_provider: "google"  # 与上面相同
    auth_required: true
    scopes: ["read"]

后端服务集成

后端MCP服务接收带有用户上下文头的信息请求:

GET /mcp HTTP/1.1
Host: calculator:3001
x-user-id: google_user_123456
x-user-email: user@example.com
x-user-name: John Doe
x-user-provider: google
x-user-avatar: https://example.com/avatar.jpg

服务可以使用这些头信息进行:

  • 用户识别和授权
  • 审计日志记录
  • 个性化响应
  • 用户特定的数据访问

高级Docker部署

从源构建

# 本地构建镜像
docker build -t mcp-oauth-gateway .

# 使用自定义构建运行
docker run -p 8080:8080 \
  -v $(pwd)/config.yaml:/app/config.yaml \
  -e GOOGLE_CLIENT_ID="your-google-client-id" \
  -e GOOGLE_CLIENT_SECRET="your-google-client-secret" \
  mcp-oauth-gateway

生产环境使用Redis存储

# 启动Redis容器
docker run -d --name redis \
  -p 6379:6379 \
  redis:alpine redis-server --requirepass mypassword

# 更新config.yaml以使用Redis
cat >> config.yaml << EOF
storage:
  type: "redis"
  redis:
    host: "host.docker.internal"  # 或Redis容器IP
    port:  6379
    password: "\${REDIS_PASSWORD}"
EOF

# 使用Redis运行网关
docker run -p 8080:8080 \
  -v $(pwd)/config.yaml:/app/config.yaml \
  -e GOOGLE_CLIENT_ID="your-google-client-id" \
  -e GOOGLE_CLIENT_SECRET="your-google-client-secret" \
  -e REDIS_PASSWORD="mypassword" \
  ghcr.io/akshay5995/mcp-oauth-gateway:latest

企业环境使用Vault存储

# 启动Vault容器(开发模式)
docker run -d --name vault \
  -p 8200:8200 \
  -e VAULT_DEV_ROOT_TOKEN_ID="myroot" \
  vault:latest

# 更新config.yaml以使用Vault
cat >> config.yaml << EOF
storage:
  type: "vault"
  vault:
    url: "http://host.docker.internal:8200"
    token: "\${VAULT_TOKEN}"
    mount_point: "secret"
    path_prefix: "mcp-gateway"
EOF

# 使用Vault运行网关
docker run -p 8080:8080 \
  -v $(pwd)/config.yaml:/app/config.yaml \
  -e GOOGLE_CLIENT_ID="your-google-client-id" \
  -e GOOGLE_CLIENT_SECRET="your-google-client-secret" \
  -e VAULT_TOKEN="myroot" \
  ghcr.io/akshay5995/mcp-oauth-gateway:latest

API端点

OAuth 2.1端点

  • GET /.well-known/oauth-authorization-server - 服务器元数据
  • GET /.well-known/oauth-protected-resource - 资源元数据
  • GET /oauth/authorize - 授权端点
  • POST /oauth/token - 令牌端点
  • POST /oauth/register - 动态客户端注册

服务端点

  • GET /services - 列出可用服务
  • GET /services/{service-id} - 获取服务信息
  • ALL /{service-id}/mcp - MCP服务代理

实用端点

  • GET / - 网关信息
  • GET /health - 健康检查

安全特性

OAuth 2.1合规性

  • 所有授权码流程都需要PKCE
  • 根据RFC 8707绑定资源参数
  • 正确的令牌受众验证
  • 安全的重定向URI验证

令牌安全

  • 带有服务特定受众声明的JWT令牌
  • 短生命周期访问令牌(1小时)
  • 公共客户端的刷新令牌轮换
  • 支持令牌撤销

提供商安全

  • 每个网关实例只有一个OAuth提供商
  • 提供商特定的用户身份验证
  • 安全的凭据存储
  • 使用状态参数进行CSRF防护

开发

运行测试

# 安装测试依赖(已包含在requirements.txt中)
pip install pytest pytest-asyncio pytest-httpx

# 运行所有测试
pytest tests/

# 运行带覆盖率的测试
pytest tests/ --cov=src

# 运行特定测试文件
pytest tests/test_oauth_server.py -v

代码风格

# 格式化和检查代码
ruff check src/ demo/ --fix
ruff format src/ demo/

环境变量

网关配置

  • MCP_CONFIG_PATH - 配置文件路径
  • MCP_GATEWAY_HOST - 主机覆盖
  • MCP_GATEWAY_PORT - 端口覆盖
  • MCP_DEBUG - 调试模式

OAuth提供商

  • GOOGLE_CLIENT_ID - Google OAuth客户端ID
  • GOOGLE_CLIENT_SECRET - Google OAuth客户端密钥
  • GITHUB_CLIENT_ID - GitHub OAuth客户端ID
  • GITHUB_CLIENT_SECRET - GitHub OAuth客户端密钥
  • OKTA_CLIENT_ID - Okta OAuth客户端ID
  • OKTA_CLIENT_SECRET - Okta OAuth客户端密钥
  • OKTA_DOMAIN - Okta域(例如,dev-123.okta.com)

存储后端

  • REDIS_HOST - Redis服务器主机
  • REDIS_PORT - Redis服务器端口
  • REDIS_PASSWORD - Redis认证密码
  • REDIS_SSL - 启用Redis SSL(true/false)
  • VAULT_URL - Vault服务器URL
  • VAULT_TOKEN - Vault认证令牌
  • VAULT_MOUNT_POINT - Vault KV挂载点
  • VAULT_PATH_PREFIX - Vault秘密路径前缀

存储后端

选择适合您部署的适当存储后端:

内存存储(默认)

storage:
  type: "memory"

最佳适用:开发、测试、单实例演示
限制:重启时数据丢失,仅限单实例

Redis存储(生产)

storage:
  type: "redis"
  redis:
    host: "${REDIS_HOST:-localhost}"
    port: 6379
    password: "${REDIS_PASSWORD}"
    ssl: true
    max_connections: 20

最佳适用:生产部署、水平扩展
特性:持久存储、多实例支持、连接池
兼容性:使用现代redis-py库以支持Python 3.11+

Vault存储(企业)

storage:
  type: "vault"
  vault:
    url: "${VAULT_URL}"
    token: "${VAULT_TOKEN}"
    mount_point: "secret"
    path_prefix: "mcp-gateway"
    auth_method: "token"  # 或"approle", "kubernetes"

最佳适用:企业环境、合规需求
特性:静态加密、审计日志、细粒度访问控制

架构

网关实现了清晰的关注点分离:

  • OAuth服务器:核心OAuth 2.1授权服务器
  • 提供商管理器:外部OAuth提供商集成
  • 客户端注册表:动态客户端注册和管理
  • 令牌管理器:JWT令牌的创建和验证
  • 存储管理器:可配置的存储后端及回退机制
  • MCP代理:带有用户上下文注入的请求转发
  • 元数据提供者:OAuth元数据端点实现

📖 查看完整架构文档

故障排除

遇到问题?查阅故障排除指南:

📚 故障排除指南 - 包括常见问题及其解决方案:

  • 原点验证错误(403响应)
  • MCP协议版本问题(400响应)
  • 令牌受众验证问题(401响应)
  • 配置和部署问题

快速链接

许可

MIT许可 - 查看LICENSE文件以获取详情。