Skip to content

AtomCode 授权协议深度分析补充 — 授权码 + PKCE + MCP OAuth 动态注册

日期: 2026-06-24 | 基于二进制静态分析和运行抓包 补充 AUTHORIZATION_PROTOCOL.md 中未覆盖的 OAuth 深层细节


1. 授权流程总结

AtomCode 支持 3 种授权模式

模式适用场景安全级别是否已覆盖
ACS OAuth 轮询AtomGit 平台登录 / CodingPlan✅ 已在 AUTHORIZATION_PROTOCOL.md 覆盖
MCP OAuth 授权码 + PKCEMCP 服务器远程认证最高本轮新增
GitHub OAuth 授权码GitHub MCP 服务器集成本轮新增

2. MCP OAuth 授权码 + PKCE 完整流程

这是 AtomCode 中最安全的授权协议,使用标准的 OAuth 2.0 Authorization Code Grant + PKCE (S256)。

2.1 核心端点

从二进制中提取的 OAuth 授权服务器元数据:

rust
struct AuthorizationServerMetadata {
    // 5 个字段
    authorization_endpoint: String,    // 授权端点 (用户浏览器)
    token_endpoint:         String,    // Token 交换端点
    registration_endpoint:  String,    // 动态客户端注册端点 (RFC 7591)
    // 2 个额外字段
}

2.2 完整授权码流程

Step 1: 发现授权服务器元数据
  GET {authorization_server}/.well-known/oauth-authorization-server
  → 解析 AuthorizationServerMetadata
  |  "Failed to fetch MCP OAuth resource metadata from {}"
  |  "Failed to parse MCP OAuth resource metadata from {}"

Step 2: 动态客户端注册(如果支持)
  POST {registration_endpoint}
  Body: {
    "client_name":          "...",
    "redirect_uris":        ["http://127.0.0.1:{port}/callback"],
    "grant_types":          ["authorization_code"],
    "response_types":       ["code"],
    "token_endpoint_auth_method": "none"  // 或 "client_secret_basic"
  }
  → 返回 client_id + client_secret
  |  "MCP OAuth dynamic client registration failed: HTTP {}"
  |  "Failed to dynamically register MCP OAuth client"
  |
  |  ⚠ 如果不支持动态注册:
  |  "MCP OAuth requires a pre-registered client_id because
  |   the authorization server does not support dynamic
  |   client registration (RFC 7591). Add a pre-registered
  |   client_id to auth.client_id in your .mcp.json..."

Step 3: PKCE 挑战生成
  code_verifier = crypto_random_string(43-128 chars)
  code_challenge = base64url(sha256(code_verifier))  // S256 方法

Step 4: 打开浏览器进行授权
  GET {authorization_endpoint}?
    response_type=authorization_code&
    client_id={client_id}&
    redirect_uri=http://127.0.0.1:{port}/callback&
    code_challenge={base64url_sha256(code_verifier)}&
    code_challenge_method=S256&
    scope={scope}&
    state={anti_csrf_token}
  
  用户浏览器打开授权页面
  → 用户登录并授权
  → 浏览器重定向到 redirect_uri?code={auth_code}&state={state}

Step 5: 绑定本地 OAuth 回调监听
  |  "Failed to bind local OAuth callback listener"
  在本地 127.0.0.1 启动临时 HTTP 服务器监听回调

Step 6: 接收回调
  |  "Failed to accept OAuth callback"
  |  "OAuth callback did not include code"
  |  "OAuth callback did not include state"
  |  "Invalid OAuth callback URL"
  |  "Invalid OAuth callback request"
  
  ✓ 验证 state (anti-CSRF)
  ✓ 提取 authorization_code

Step 7: 交换 Token
  POST {token_endpoint}
  Body: {
    "grant_type":   "authorization_code",
    "code":         "{auth_code}",
    "code_verifier": "{code_verifier}",
    "redirect_uri": "http://127.0.0.1:{port}/callback",
    "client_id":    "{client_id}"
  }
  → 返回 TokenResponse
  |  "Failed to exchange MCP OAuth code"
  |  "Failed to parse MCP OAuth token response"

Step 8: 存储 Token
  存储为 McpOAuthToken (11 字段)

2.3 MCP OAuth Token 存储结构

rust
struct McpOAuthToken {
    // 11 个元素 — 最复杂的认证相关结构体
    access_token:           String,
    token_type:             String,     // Bearer
    expires_in:             Option<u64>,
    refresh_token:          Option<String>,
    scope:                  Option<String>,
    client_id:              Option<String>,
    client_secret:          Option<String>,
    client_secret_env:      Option<String>,  // 环境变量引用
    // ... 3 个额外字段
}

3. GitHub MCP OAuth 集成

3.1 GitHub MCP 服务器认证

GitHub MCP 有专门的处理逻辑:

rust
// GitHub MCP 的特殊端点
"https://api.githubcopilot.com/mcp/"
"https://github.com/login/oauth/authorize"    // GitHub OAuth 授权
"https://github.com/login/oauth/access_token" // Token 交换

// 特定错误处理
"GitHub MCP OAuth requires --client-secret-env or auth.client_secret_env in mcp.json"
"GitHub OAuth client id is required"
"Failed to exchange GitHub OAuth code"
"Failed to parse GitHub OAuth token response"

3.2 GitHub OAuth 流程

环境变量或配置中提供 client_id 和 client_secret:
  ATOMCODE_GITHUB_MCP_CLIENT_ID (环境变量)
  或 auth.client_secret_env (mcp.json 配置)

→ https://github.com/login/oauth/authorize 发起授权
→ 用户 GitHub 授权页面
→ 回调 → code 交换
→ POST https://github.com/login/oauth/access_token
→ 获取 GitHub Copilot MCP 的 access_token

4. ACS 平台 OAuth 流程(补充 AUTHORIZATION_PROTOCOL.md

4.1 平台登录完整 API

从二进制中提取的平台认证结构体:

rust
struct PlatformLoginResponse {
    auth_url:   String,     // 授权 URL
    login_id:   String,     // 登录会话 ID
}

struct PlatformCheckResponse {
    logged_in:  bool,       // 是否已登录
}

struct PlatformTokenResponse {
    // 5 个元素
    access_token:   String,
    token_type:     String,
    expires_in:     u64,
    refresh_token:  Option<String>,
    scope:          Option<String>,
}

struct PlatformUserInfo {
    // 5 个元素
    id:     String,
    login:  String,
    name:   String,
    avatar: String,
    // 1 个额外字段
}

4.2 Token 自动刷新

rust
// 刷新逻辑
"OAuth token is expired and has no refresh token"
"OAuth token is expired; run 'atomcode mcp login <server>'"
"Token expired"
"Token refresh failed"

struct RefreshedAuth {
    access_token:   String,
    token_type:     String,
    expires_in:     u64,
    refresh_token:  Option<String>,
    // 1 个额外字段
}

struct RefreshedUser {
    id:     String,
    login:  String,
    name:   String,
    avatar: String,
    // 1 个额外字段
}

5. ACS 短链接轮询登录(补充细节)

AUTHORIZATION_PROTOCOL.md 已覆盖了轮询流程,补充二进制中发现的错误处理字符串:

rust
// 平台认证相关
"please use /login first"
"Login session not found or expired"
"Login still pending. Poll /auth/login/:login_id/poll until authorized."

// 平台服务器配置
ATOMCODE_PLATFORM_SERVER = "https://acs.atomgit.com"
"&force_login=true"   // 短链接重定向时强制登录参数

MCP OAuth 的额外配置

mcp.json 中的认证配置字段:

json
{
  "auth": {
    "client_id":           "xxx",          // 预注册的 client_id
    "client_secret_env":   "MY_SECRET",    // 引用环境变量
    "authorization_servers": ["..."]       // 授权服务器元数据 URL
  }
}

6. 授权相关文件

~/.atomcode/
├── auth.toml                 → OAuth token 存储
│     access_token / refresh_token / token_type / expires_in / created_at
│     [user] id / login / name / email / avatar_url

├── .mcp.json                 → MCP 服务器配置(含 OAuth 字段)

└── sessions/
    └── ...                   → 会话文件(含 OAuth 状态)

7. 总结

#授权机制协议安全性已覆盖
1ACS 平台 OAuth + 轮询 (AtomGit 登录)自定义✅ 已有 + 本轮补充
2MCP OAuth 授权码 + PKCE + 动态客户端注册RFC 6749 + RFC 7636 + RFC 7591最高本轮新增
3GitHub MCP OAuth (Copilot 集成)授权码 + client_secret本轮新增
4Token 自动刷新Refresh Token✅ 本轮补充

总结:AtomCode 完整实现了 OAuth 2.0 授权码授权流 + PKCE 扩展(S256)—— 这是目前移动端和单页应用推荐的最安全认证模式。 同时支持 RFC 7591 动态客户端注册和传统的预注册 client_id 方式。


本报告由持续分析生成 — 授权深度分析补充

逆向命令索引

bash
# 提取 OAuth 相关字符串
strings atomcode.bin.bak | grep -iE "oauth|pkce|authorization.code|authorization_server|client_secret" | sort -u | head -15

# 提取登录端点
strings atomcode.bin.bak | grep -E "/auth/login|/auth/token|/auth/status" | sort -u

# 运行时验证
TOKEN=$(python3 -c "import tomllib; f=open('$HOME/.atomcode/auth.toml','rb');print(tomllib.load(f)['access_token'])")
curl -s -H "Authorization: Bearer $TOKEN" http://localhost:13456/auth/status 2>/dev/null

基于 VitePress 构建 · AtomCode v4.25.3 逆向工程分析文档