使用说明
MCP OAuth网关
[⚠️⚠️⚠️ 概念验证(PoC)不适合生产使用⚠️⚠️⚠️]
OAuth 2.1授权服务器,为模型上下文协议(MCP)服务提供透明的身份验证和授权。
特性
- 透明MCP访问:用户通过简单的URL访问MCP服务,无需手动设置OAuth
- 单一OAuth提供者:为所有服务(Google、GitHub、Okta或自定义)使用一个OAuth提供程序
- 完全符合MCP:使用OAuth 2.1实现完整的MCP授权规范
- 动态客户端注册:根据RFC 7591自动注册客户端
- 用户上下文注入:后端MCP服务的无缝用户上下文标头
- 资源特定令牌:RFC 8707受众绑定防止令牌滥用
- 可配置存储:内存(开发)、Redis(生产)、Vault(企业)后端
- 生产就绪:全面的测试、Docker支持、可扩展的架构
Docker快速入门(推荐)
预构建图像
使用GitHub容器注册表中的预构建Docker镜像:
# Run with memory storage (development)
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(全栈)
# Copy environment template
cp .env.example .env
# Edit .env with your OAuth credentials
# Start all services (gateway + Redis + demo calculator)
docker-compose up -d
# Test the setup
curl http://localhost:8080/health
curl http://localhost:8080/calculator/mcp # Should return 401 with OAuth info
地方发展设置
1.安装依赖项
pip install -r requirements.txt
# Optional: For Redis storage backend with modern library
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 文件:
# Gateway settings
host: "localhost"
port: 8080
issuer: "http://localhost:8080"
session_secret: "your-dev-secret-change-in-production"
debug: true
# OAuth provider
oauth_providers:
google:
client_id: "${GOOGLE_CLIENT_ID}"
client_secret: "${GOOGLE_CLIENT_SECRET}"
scopes: ["openid", "email", "profile"]
# Example service (replace with your MCP service)
mcp_services:
calculator:
name: "Calculator Service"
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
# Should return 401 with OAuth authentication info
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=My MCP Client" \
-d "redirect_uris=http://localhost:8080/callback"
4.授权流程
客户端遵循标准OAuth 2.1和PKCE:
- 带有资源参数的授权请求
- 通过配置的提供程序进行用户身份验证
- 访问令牌的授权码交换
- 经过身份验证的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: ["*"] # Allowed origins (use specific domains in production)
allow_credentials: true # Allow credentials in CORS requests
allow_methods: # Allowed HTTP methods
- "GET"
- "POST"
- "PUT"
- "DELETE"
- "OPTIONS"
allow_headers: ["*"] # Allowed headers (use specific headers in production)
对于生产部署,限制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: "Calculator Service"
url: "http://calculator:3001"
oauth_provider: "google" # Must match the configured OAuth provider
auth_required: true
scopes: ["read", "calculate"]
timeout: 30000
# All authenticated services must use the same OAuth provider
weather:
name: "Weather Service"
url: "http://weather:3002"
oauth_provider: "google" # Same as above
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部署
从源代码构建
# Build image locally
docker build -t mcp-oauth-gateway .
# Run with custom build
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存储进行生产
# Start Redis container
docker run -d --name redis \
-p 6379:6379 \
redis:alpine redis-server --requirepass mypassword
# Update config.yaml for Redis
cat >> config.yaml << EOF
storage:
type: "redis"
redis:
host: "host.docker.internal" # or Redis container IP
port: 6379
password: "\${REDIS_PASSWORD}"
EOF
# Run gateway with 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存储的企业
# Start Vault container (dev mode)
docker run -d --name vault \
-p 8200:8200 \
-e VAULT_DEV_ROOT_TOKEN_ID="myroot" \
vault:latest
# Update config.yaml for 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
# Run gateway with 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保护
发展
运行测试
# Install test dependencies (included in requirements.txt)
pip install pytest pytest-asyncio pytest-httpx
# Run all tests
pytest tests/
# Run with coverage
pytest tests/ --cov=src
# Run specific test file
pytest tests/test_oauth_server.py -v
代码风格
# Format and lint code
ruff check src/ demo/ --fix
ruff format src/ demo/
环境变量
网关配置
MCP_CONFIG_PATH-配置文件的路径MCP_GATEWAY_HOST-主机覆盖MCP_GATEWAY_PORT-端口覆盖MCP_DEBUG-调试模式
OAuth提供者
GOOGLE_CLIENT_ID-谷歌OAuth客户端IDGOOGLE_CLIENT_SECRET-Google OAuth客户端密钥GITHUB_CLIENT_ID-GitHub OAuth客户端IDGITHUB_CLIENT_SECRET-GitHub OAuth客户端密钥OKTA_CLIENT_ID-Okta OAuth客户端IDOKTA_CLIENT_SECRET-Okta OAuth客户端密钥OKTA_DOMAIN-Okta域名(例如dev-123.Okta.com)
存储后端
REDIS_HOST-Redis服务器主机REDIS_PORT-Redis服务器端口REDIS_PASSWORD-Redis身份验证密码REDIS_SSL-启用Redis SSL(真/假)VAULT_URL-保险库服务器URLVAULT_TOKEN-保险库身份验证令牌VAULT_MOUNT_POINT-保险库KV安装点VAULT_PATH_PREFIX-保险库秘密路径前缀
存储后端
为您的部署选择合适的存储后端:
内存存储(默认)
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+兼容性
保险库存储(企业)
storage:
type: "vault"
vault:
url: "${VAULT_URL}"
token: "${VAULT_TOKEN}"
mount_point: "secret"
path_prefix: "mcp-gateway"
auth_method: "token" # or "approle", "kubernetes"
✅ 最佳:企业环境、法规遵从性要求
✅ 特性:静态加密、审计日志记录、细粒度访问控制
建筑
网关实现了关注点的清晰分离:
- OAuth服务器:核心OAuth 2.1授权服务器
- 供应商经理:外部OAuth提供程序集成
- 客户端注册表:动态客户注册和管理
- 令牌管理器:JWT令牌创建和验证
- 存储管理器:具有回退功能的可配置存储后端
- MCP代理:使用用户上下文注入进行请求转发
- 元数据提供程序:OAuth元数据端点实现
故障排除
有问题吗?查看故障排除指南:
📚 故障排除指南 -常见问题和解决方案包括:
- 源验证错误(403个响应)
- MCP协议版本问题(400个响应)
- 令牌受众验证问题(401条回复)
- 配置和部署问题
快速链接
许可证
MIT许可证-有关详细信息,请参阅许可证文件。