OAuth MCP代理
Go MCP服务器的OAuth 2.1身份验证库。
支持两个MCP SDK:
- ✅
mark3labs/mcp-go - ✅
modelcontextprotocol/go-sdk(官方)
一次性设置: 配置提供者+添加 WithOAuth() 到您的服务器。 结果: 所有工具都通过令牌验证和缓存自动保护。
mark3labs/mcp go
import "github.com/tuannvm/oauth-mcp-proxy/mark3labs"
oauthServer, oauthOption, _ := mark3labs.WithOAuth(mux, &oauth.Config{
Provider: "okta",
Issuer: "https://your-company.okta.com",
Audience: "api://your-mcp-server",
})
mcpServer := server.NewMCPServer("Server", "1.0.0", oauthOption)
streamable := server.NewStreamableHTTPServer(mcpServer, /*options*/)
mux.HandleFunc("/mcp", oauthServer.WrapMCPEndpoint(streamable))官方SDK
import mcpoauth "github.com/tuannvm/oauth-mcp-proxy/mcp"
mcpServer := mcp.NewServer(&mcp.Implementation{...}, nil)
_, handler, _ := mcpoauth.WithOAuth(mux, cfg, mcpServer)
http.ListenAndServe(":8080", handler)](https://github.com/tuannvm/oauth-mcp-proxy/actions/workflows/test.yml) ](https://github.com/tuannvm/oauth-mcp-proxy/blob/main/go.mod)   ](https://github.com/tuannvm/oauth-mcp-proxy/releases/latest) 
______________________________________________________________________
为什么要使用这个图书馆?
- 双SDK支持 -适用于mark3labs和官方SDK
- 简单集成 -一个
WithOAuth()调用保护所有工具 - 自动401处理 -符合RFC 6750的OAuth发现错误响应
- 每个工具配置为零 -所有工具自动保护
- 快速令牌缓存 -具有JWT过期感知的5分钟缓存
- 加强安保 -状态重放保护、DoS防御、输入验证
- 内置速率限制 -包括基于令牌的速率限制器
- CORS支持 -浏览器客户端传递选项
- 多个供应商 -HMAC、Okta、谷歌、Azure广告
______________________________________________________________________
运作原理
请求流
sequenceDiagram
participant Client
participant MCP Server
box lightyellow oauth-mcp-proxy Library
participant Middleware
participant Cache
participant Provider
end
participant Your Tool Handler
Client->>MCP Server: Request + Bearer token
MCP Server->>Middleware: WithOAuth() intercepts
alt Token in cache and fresh
Middleware->>Cache: Check token hash
Cache-->>Middleware: Return cached user
else Token not cached or expired
Middleware->>Provider: Validate token (HMAC/OIDC)
Provider-->>Middleware: User claims
Middleware->>Cache: Store user for 5 minutes
end
Middleware->>Your Tool Handler: Pass request with user in context
Your Tool Handler->>Your Tool Handler: GetUserFromContext(ctx)
Your Tool Handler-->>Client: Send response令牌验证流程
flowchart TB
Start([Your MCP Server receives request]) --> Extract[oauth-mcp-proxy: Extract Token]
Extract --> Hash[oauth-mcp-proxy: SHA-256 Hash]
Hash --> CheckCache{oauth-mcp-proxy: Token Cached?}
CheckCache -->|Cache Hit| GetUser[oauth-mcp-proxy: Get Cached User]
CheckCache -->|Cache Miss| Validate{oauth-mcp-proxy: Validate}
Validate -->|Valid| Claims[oauth-mcp-proxy: Extract Claims]
Validate -->|Invalid| Reject([Return 401])
Claims --> Store[oauth-mcp-proxy: Cache]
Store --> GetUser
GetUser --> Context[oauth-mcp-proxy: Add User to Context]
Context --> Tool[Your Tool Handler: GetUserFromContext]
Tool --> Response([Your MCP Server: Return Response])
style Start fill:#e8f5e9
style Extract fill:#fff9c4
style Hash fill:#fff9c4
style CheckCache fill:#fff9c4
style Validate fill:#fff9c4
style Claims fill:#fff9c4
style Store fill:#fff9c4
style GetUser fill:#fff9c4
style Context fill:#fff9c4
style Tool fill:#e8f5e9
style Response fill:#e8f5e9
style Reject fill:#ffebeeoauth-mcp代理的功能:
- 从HTTP请求中提取承载令牌
- 根据您的OAuth提供程序进行验证(使用缓存)
- 将经过身份验证的用户添加到请求上下文中
- 您的所有工具都会自动受到保护
______________________________________________________________________
🔒 安全特性
内置生产就绪安全强化功能:
状态回放保护
- 时间戳+随机数验证 -状态包括防止重放攻击的时间戳和随机数
- 自动随机数清理 -在重播检查之前删除过期的非字符(防止内存泄漏)
- 滚动部署兼容 -接受没有时间戳/随机数的遗留状态,实现零停机升级
令牌安全
- JWT过期感知缓存 -缓存尊重令牌过期时间(使用min(token.expiry,现在+5min))
- 恒定时间HMAC比较 -签名验证的定时攻击防御
- 安全的随机数生成 -加密货币/兰特失败引发恐慌(没有弱回退)
输入验证和DoS防御
- 参数长度限制 -验证代码、状态、代码挑战以防止滥用
- 请求车身尺寸限制 -令牌端点上的MaxBytesLeader(1MB),注册(256KB)
- 发卡机构URL验证 -非本地主机OIDC提供商强制HTTPS
会话管理(官方SDK)
- auth。TokenInfo人口 -为会话绑定填充go-sdk-auth上下文
- 基于用户的会话跟踪 -通过用户ID验证防止会话劫持
HTTP安全
- 安全标头 -CSP、X帧选项、X内容类型选项、缓存控制
- CORS支持 -浏览器客户端传递选项
- 符合RFC 6750 -使用resource_metadata正确验证WWW标头
内置速率限制
// Simple token-based rate limiter included
limiter := oauth.NewRateLimiter(time.Minute, 100)
if !limiter.Allow("client-ip") {
http.Error(w, "Rate limit exceeded", http.StatusTooManyRequests)
}______________________________________________________________________
突破性变化(安全强化)
v1.0.0→ v1.1.0版本
以下安全改进介绍 重大变更:
1.发卡机构URL验证(关键)
- 改变:OIDC提供商现在对发行者URL强制执行HTTPS验证
- 影响:无效的发行者URL将导致
NewServer()失败 - 迁移:确保您的
Issuer配置使用HTTPS(或本地主机进行测试)
// ✅ Valid
Issuer: "https://company.okta.com"
Issuer: "http://localhost:8080" // Testing only
// ❌ Invalid - will fail validation
Issuer: "http://company.okta.com" // Not localhost
Issuer: "company.okta.com" // Missing scheme2.状态签名密钥初始化
- 改变:
NewServer()现在,如果无法生成状态签名密钥,就会恐慌 - 影响:如果crypto/rand失败,服务器启动将失败(在健康的系统上永远不会发生)
- 迁移:确保您的系统有一个正常工作的CSPRNG。不需要更改代码。
3.非发电故障行为
- 改变:
generateSecureNonce()现在恐慌,而不是回到基于时间戳的弱nonce - 影响:如果crypto/rand失败,OAuth授权请求将失败
- 迁移:确保您的系统有一个正常工作的CSPRNG。不需要更改代码。
4.错误消息简化
- 改变:安全敏感错误消息不那么冗长,以防止信息泄露
- 影响:调试身份验证失败可能需要检查日志
- 迁移:使用服务器日志进行详细调试;客户端错误是有意通用的
无需迁移
- 令牌缓存过期修复 -完全向后兼容
- 状态重放保护 -仍然接受没有时间戳/随机数的遗留状态
- 输入验证 -仅影响格式错误的请求
- go-sdk适配器修复 -完全向后兼容
______________________________________________________________________
快速开始
使用mark3labs/mcp-go
1.安装
go get github.com/tuannvm/oauth-mcp-proxy2.添加到您的服务器
import (
oauth "github.com/tuannvm/oauth-mcp-proxy"
"github.com/tuannvm/oauth-mcp-proxy/mark3labs"
)
mux := http.NewServeMux()
// Enable OAuth (one time setup)
oauthServer, oauthOption, _ := mark3labs.WithOAuth(mux, &oauth.Config{
Provider: "okta", // or "hmac", "google", "azure"
Issuer: "https://your-company.okta.com",
Audience: "api://your-mcp-server",
ServerURL: "https://your-server.com",
})
// Create MCP server with OAuth
mcpServer := mcpserver.NewMCPServer("Server", "1.0.0", oauthOption)
// Add tools - all automatically protected
mcpServer.AddTool(myTool, myHandler)
// Setup endpoint with automatic 401 handling
streamable := mcpserver.NewStreamableHTTPServer(
mcpServer,
mcpserver.WithHTTPContextFunc(oauth.CreateHTTPContextFunc()),
)
mux.HandleFunc("/mcp", oauthServer.WrapMCPEndpoint(streamable))3.访问经过身份验证的用户
func myHandler(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
user, ok := oauth.GetUserFromContext(ctx)
if !ok {
return nil, fmt.Errorf("authentication required")
}
// Use user.Username, user.Email, user.Subject
}______________________________________________________________________
使用官方SDK
1.安装
go get github.com/modelcontextprotocol/go-sdk
go get github.com/tuannvm/oauth-mcp-proxy2.添加到您的服务器
import (
"github.com/modelcontextprotocol/go-sdk/mcp"
oauth "github.com/tuannvm/oauth-mcp-proxy"
mcpoauth "github.com/tuannvm/oauth-mcp-proxy/mcp"
)
mux := http.NewServeMux()
// Create MCP server
mcpServer := mcp.NewServer(&mcp.Implementation{
Name: "my-server",
Version: "1.0.0",
}, nil)
// Add tools
mcp.AddTool(mcpServer, &mcp.Tool{
Name: "greet",
Description: "Greet user",
}, func(ctx context.Context, req *mcp.CallToolRequest, params *struct{}) (*mcp.CallToolResult, any, error) {
user, _ := oauth.GetUserFromContext(ctx)
return &mcp.CallToolResult{
Content: []mcp.Content{
&mcp.TextContent{Text: "Hello, " + user.Username},
},
}, nil, nil
})
// Add OAuth protection
_, handler, _ := mcpoauth.WithOAuth(mux, &oauth.Config{
Provider: "okta",
Issuer: "https://your-company.okta.com",
Audience: "api://your-mcp-server",
}, mcpServer)
http.ListenAndServe(":8080", handler)您的MCP服务器现在需要OAuth身份验证。
______________________________________________________________________
例子
看 示例/README.md 获取包括Okta配置在内的详细设置指南。
| SDK | 示例 | 说明 |
|---|---|---|
| mark3labs | 简单 | 最小设置-复制/粘贴就绪 |
| mark3labs | 高级 | ConfigBuilder、多种工具、日志记录 |
| 官方 | 简单 | 最小设置-复制/粘贴就绪 |
| 官方 | 高级 | ConfigBuilder、多种工具、日志记录 |
______________________________________________________________________
支持的提供商
| 提供商 | 最佳选择 | 安装指南 |
|---|---|---|
| HMAC | 测试、开发 | 文档/提供者/HAC.md |
| 八月 | 企业SSO | 文档/提供者/OKTA.md |
| 谷歌 | 谷歌工作区 | 文档/提供者/GOOGLE.md |
| Azure AD | 微软365 | docs/providers/AZURE.md |
______________________________________________________________________
文档
入门指南:
高级:
______________________________________________________________________
许可证
MIT许可证-请参阅 许可证
