OAuth认证库

为Go MCP服务器提供OAuth 2.1认证功能的库,支持双SDK集成和自动令牌验证。

  • by tuannvm
  • Go
  • 本地部署
  • 33 星标
  • 更新于
在 GitHub 查看 tuannvm/oauth-mcp-proxy

使用说明

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)

为什么要使用这个图书馆?

  • 双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:#ffebee

oauth-mcp代理的功能:

  1. 从HTTP请求中提取承载令牌
  2. 根据您的OAuth提供程序进行验证(使用缓存)
  3. 将经过身份验证的用户添加到请求上下文中
  4. 您的所有工具都会自动受到保护

🔒 安全特性

内置生产就绪安全强化功能:

状态回放保护

  • 时间戳+随机数验证 -状态包括防止重放攻击的时间戳和随机数
  • 自动随机数清理 -在重播检查之前删除过期的非字符(防止内存泄漏)
  • 滚动部署兼容 -接受没有时间戳/随机数的遗留状态,实现零停机升级

令牌安全

  • 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 scheme
    

2.状态签名密钥初始化

  • 改变: 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-proxy

2.添加到您的服务器

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-proxy

2.添加到您的服务器

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许可证-请参阅 许可证