OAuth2代理服务

一个兼容OAuth 2.1的授权服务器和反向代理,旨在为零修改上游MCP HTTP服务器的情况下添加认证功能。

  • by clems4ever
  • Go
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 clems4ever/mcp-oauth2-go

使用说明

mcp-oauth2-羟基

一个兼容OAuth 2.1的授权服务器和反向代理,旨在为普通用户添加身份验证 模型上下文协议(MCP) HTTP服务器,上游没有变化。

它位于MCP服务器的前面,处理所有OAuth流,在每个请求上验证Bearer令牌,并将经过身份验证的流量转发到上游。

特征

  • 授权码流 使用PKC(S256)——由Claude等MCP客户端使用
  • 刷新令牌流 使用轮转--客户端无需重新验证即可续订访问令牌
  • 客户端凭据流 --机器对机器访问
  • 基于浏览器的登录表单,带有bcrypt密码验证
  • 可选的 OpenID连接登录 (例如谷歌)在密码表单旁边显示电子邮件分配列表
  • JWT访问令牌(HS256) iss, aud, sub, exp 索赔
  • 自动发现端点(RFC 8414+RFC 9728)
  • 上游MCP HTTP服务器的透明反向代理

快速开始

git clone https://github.com/clems4ever/mcp-oauth2-proxy
cd mcp-oauth2-proxy
go build -o mcp-oauth2-proxy .
./mcp-oauth2-proxy --config example-config.yaml

或者使用Docker:

docker run --rm \
  -p 8080:8080 \
  -v $PWD/example-config.yaml:/config.yaml \
  ghcr.io/clems4ever/mcp-oauth2-proxy --config /config.yaml

配置

server:
  port: 8080
  issuer: "https://auth.example.com"   # public base URL — must match what clients see
  jwt_secret: "change-me-in-production"
  token_ttl: 3600           # access token lifetime, seconds
  auth_code_ttl: 300        # authorization code lifetime, seconds
  refresh_token_ttl: 2592000 # refresh token lifetime, seconds (default 30 days)
  upstream_url: "http://localhost:9090" # MCP HTTP server to proxy authenticated requests to

# Human users for the authorization code flow.
# Passwords are bcrypt hashes — generate with: htpasswd -bnBC 10 "" <password> | tr -d ':\n'
users:
  - username: alice
    password: "$2a$10$..."

# Single OAuth2 application (used for both flows).
application:
  client_id: "service-client-id"
  client_secret: "service-client-secret"
  allowed_scopes:
    - read
    - write
  redirect_uris:
    - "https://claude.ai/api/mcp/auth_callback"

默认配置路径: ~/.mcp-oauth2.yaml.用覆盖 --config.

以下各节分别记录了两个可选块: oidc (登录 与谷歌/任何OIDC提供商合作)以及 storage (将刷新令牌持久化到磁盘)。

端点

方法 路径 描述
GET /.well-known/oauth-authorization-server 授权服务器元数据(RFC 8414)
GET /.well-known/oauth-protected-resource 受保护的资源元数据(RFC 9728)
GET/POST /oauth2/authorize 授权端点--显示登录表单,发出身份验证码
POST /oauth2/token 令牌端点-- authorization_code, client_credentials 和 refresh_token 赠款
POST /oauth2/oidc/login 启动OIDC登录(仅当 oidc 已配置)
GET /oauth2/oidc/callback OIDC提供商回调(仅当 oidc 已配置)
* / 反向代理到 upstream_url (需要有效的Bearer令牌)

令牌端点

客户端凭据

curl -X POST http://localhost:8080/oauth2/token \
  -u service-client-id:service-client-secret \
  -d "grant_type=client_credentials&scope=read"

授权码(PKCE)

授权码流由MCP客户端启动。代理显示登录表单,用户进行身份验证,并向注册者返回授权码 redirect_uri。然后将代码交换为令牌:

curl -X POST http://localhost:8080/oauth2/token \
  -u service-client-id:service-client-secret \
  -d "grant_type=authorization_code&code=<code>&redirect_uri=<uri>&code_verifier=<verifier>"

授权码响应包括 refresh_token.

刷新令牌

将刷新令牌替换为新的访问令牌(以及旋转的刷新令牌)。 之前的刷新令牌在使用时无效;可选 scope 可能缩小 授予的范围(它必须是原始范围的子集):

curl -X POST http://localhost:8080/oauth2/token \
  -u service-client-id:service-client-secret \
  -d "grant_type=refresh_token&refresh_token=<refresh_token>"

仅为授权码(和刷新)流颁发刷新令牌-- 这 client_credentials grant不返回任何值,因为机器客户端可以简单地 请求一个新的令牌及其凭据。

默认情况下,刷新令牌保存在内存中,并在重新启动时丢失。进行登录 生存重启,设置 storage.path 将它们保存在嵌入式系统中 bbolt 数据库(清除过期的令牌 自动):

storage:
  path: "/var/lib/mcp-oauth2/store.db"

授权码和登录会话始终在内存中(它们是 短命)。

响应

{
  "access_token": "eyJhbGci...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "9f8c...",
  "scope": "read write"
}

Google/OIDC登录

除了密码表单,浏览器登录还可以对用户进行身份验证 针对任何OpenID Connect提供商(谷歌、Okta、Auth0、Entra等)。当A oidc 如果配置中存在块,登录页面将显示 “登录 谷歌 用户名/密码窗体旁边的按钮。访问仅限于 电子邮件列表 --只有您列出的经过验证的电子邮件才能登录。

  1. 在您的提供商处创建OAuth客户端。对于谷歌: API和服务→ 凭证→ 创建OAuth客户端ID→ Web应用程序.
  2. 将此代理的回调添加为授权重定向URI: <issuer base URL>/oauth2/oidc/callback (例如。 https://auth.example.com/oauth2/oidc/callback).
  3. 添加 oidc 阻止您的配置:
oidc:
  issuer: "https://accounts.google.com"   # OIDC issuer; endpoints are discovered automatically
  client_id: "xxxxxxxx.apps.googleusercontent.com"
  client_secret: "your-google-client-secret"
  # redirect_url defaults to <server.issuer>/oauth2/oidc/callback
  scopes: ["openid", "email", "profile"]  # optional; this is the default
  allowed_emails:
    - alice@example.com

工作原理:代理将浏览器重定向到提供商,验证 返回的ID令牌(签名、受众、随机数)和 email_verified,检查 电子邮件反对 allowed_emails,然后发布自己的授权码——所以 下游MCP令牌交换不变。已发放的访问令牌 sub 索赔是用户的电子邮件。

旗帜

标志 默认值 描述
--config ~/.mcp-oauth2.yaml 配置文件的路径

安全说明

  • PKC与 S256 是所有授权代码流所必需的(OAuth 2.1)
  • 用户密码必须存储为bcrypt哈希值
  • A. jwt_secret 是 必需的:服务器拒绝从空服务器开始。在生产中使用强随机值
  • 这 issuer 值取自config--request Host 标头永远不受信任
  • 代理提供纯HTTP;在它前面终止TLS(例如反向代理),因为否则令牌和密码将以明文形式传输