Files
blackbird/docs/reports/auth_service_plan.md
T
qing 1e34348d6c docs: 整理文档模块——归位散落文件、修复双扩展名、补全 INDEX 索引
- 移动 docs/ 根目录散落文件到 reports/(auth_service_plan、aibox_file_network_cli_refactor、blackbird_promo_full)
- 修复 blackbird_research_report.md.md 双扩展名 → blackbird_research_report.md
- INDEX.md 补全缺失条目:dnfs2/fsys/libsqlite3/libth 安全审计,blackbird_research_report、aibox_open_dev_plan 等报告,dnfs2/fsys/libmsg/libtry README
- 更新目录树结构(security 25 篇、reviews 3 篇、reports 8 篇)
- 修正模块描述(BotOps、lci 说明更准确)
- 收录此前未跟踪的 actpred_CODE_AUDIT_20260808.md
2026-08-08 15:55:21 +00:00

374 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 权限系统独立化计划书
## 一、现状分析
### 1.1 当前架构
```
客户端 ──HTTPS──▶ WAF:443 ──HTTP──▶ gateway:8443 ──HTTP──▶ 下游服务
( auth + proxy + captcha + rate-limit + ws-proxy )
│
┌───────────────┼───────────────┐
▼ ▼ ▼
db:8005 captcha:8009 smtp:8008
(Users表) (图形验证码) (邮件发送)
下游鉴权调用链:
core:5200 ──HTTP POST──▶ gateway:/admin/verify (管理员验签)
dnfs2:8006 ──HTTP POST──▶ gateway:/whoami (Token 验签)
```
### 1.2 Gateway 职责清单(main.cpp 2508 行,单文件)
| 职责域 | 函数/组件 | 行数占比 |
|--------|-----------|---------|
| **用户认证** | handleLogin, handleRegister, handleLogout, handleResetPassword, handleSendEmailCode, handleResetSendCode, PBKDF2Hasher, PasswordValidator | ~40% |
| **Token 管理** | verify_token, generate_jti, revoke_jti, revoke_all_user_tokens, handleRefreshToken, handleWhoami, handleAdminVerify, TokenInfo, JtiDenylist, UserVerMap | ~25% |
| **CAPTCHA** | handleCaptcha, handleCaptchaImage, CaptchaEntry, generate_captcha_text, verify_captcha | ~8% |
| **速率限制** | 8 个 RateLimiter 实例(login/register/email/refresh/reset 等) | ~5% |
| **HTTP 反向代理** | handleProxy, is_special_header, is_safe_target | ~12% |
| **WebSocket 代理** | verifyWsAdminToken, ws_proxy 路由注册 | ~5% |
| **配置/基础设施** | main(), registerRoutes(), ConfIni, DbC, LogC, 信号处理 | ~5% |
### 1.3 核心问题
1. **职责严重耦合**:auth(~65%代码量)与 proxy(~17%)捆绑在同一进程,任一域的重构/扩展都影响全局
2. **不可独立扩展**:认证密集型场景(批量登录/注册)和代理密集型场景(大文件传输)无法分别扩容
3. **安全隔离缺失**:密码哈希、RSA 私钥、Token 黑名单等敏感数据与代理逻辑共存于同一进程内存空间
4. **下游耦合 gateway**:core/dnfs2 通过 HTTP 回调 gateway 做验签,gateway 既是流量入口又是认证权威,形成环形依赖
5. **单文件维护瓶颈**:2508 行 C++ 单文件,所有功能交叉耦合,测试和 code review 成本高
6. **Token 状态纯内存**:jti 黑名单和版本号在 gateway 重启后丢失(虽然 RSA 密钥同步重建可兜底,但限制了多实例部署)
---
## 二、目标架构
```
客户端 ──HTTPS──▶ WAF:443 ──HTTP──▶ gateway:8443 ──HTTP──▶ 下游服务
( 纯反向代理 + Token 透传 )
│
▼
auth:8444 (独立权限服务)
┌────┼────┐
▼ ▼ ▼
db:8005 captcha smtp
下游鉴权调用链(改造后):
core:5200 ──pymsg──▶ auth:8444:/verify (管理员验签)
dnfs2:8006 ──pymsg──▶ auth:8444:/whoami (Token 验签)
gateway ──pymsg──▶ auth:8444:/verify (代理转发前的 Token 校验)
```
### 2.1 职责划分
| 模块 | 改造后职责 |
|------|-----------|
| **auth(新)** | 用户注册/登录/注销、Token 签发/验签/刷新/吊销、CAPTCHA、密码重置、邮箱验证码、速率限制、管理员验证 |
| **gateway(精简)** | HTTP/WebSocket 反向代理、Target-Url 白名单过滤、XFF 注入、CORS 预检;认证路由(/login, /register 等)作为代理目标指向 auth |
| **core / dnfs2** | 验签调用目标由 gateway 改为 auth(pymsg 协议,消除 HTTP 回调) |
---
## 三、实施阶段
### 阶段一:auth 服务搭建(核心剥离)
**目标**:将认证逻辑整体迁入独立 C++ 服务
**新建目录结构**:
```
auth/
├── src/
│ └── main.cpp # 入口 + 路由注册
├── inc/
│ ├── AuthService.hpp # 核心认证逻辑(PBKDF2、Token 签发/验签/吊销)
│ ├── RateLimiter.hpp # 速率限制器(从 gateway 迁移)
│ ├── CaptchaService.hpp # CAPTCHA 生成/验证
│ ├── DbC.hpp # 复用 gateway 的 DbC(提取为公共库或复制)
│ ├── LogC.hpp # 复用 LogC
│ ├── Conf.hpp # 复用 ConfIni
│ ├── LocalTime.hpp # 复用
│ └── ExpBase.hpp # 复用
├── Makefile
├── _run.sh
├── _set.sh
└── README.md
```
**迁移清单**(从 gateway/src/main.cpp 提取):
| 组件 | 源位置 | 目标文件 |
|------|--------|---------|
| PBKDF2Hasher | main.cpp L62-85 | AuthService.hpp |
| PasswordValidator | main.cpp L87-160 | AuthService.hpp |
| TokenInfo / generate_jti / verify_token / revoke_* | main.cpp L340-760 | AuthService.hpp |
| handleLogin | main.cpp L1346-1525 | main.cpp (auth) |
| handleRegister | main.cpp L1891-1981 | main.cpp (auth) |
| handleLogout | main.cpp L1527-1554 | main.cpp (auth) |
| handleWhoami | main.cpp L1556-1606 | main.cpp (auth) |
| handleAdminVerify | main.cpp L1608-1657 | main.cpp (auth) |
| handleRefreshToken | main.cpp L1672-1837 | main.cpp (auth) |
| handleSendEmailCode | main.cpp ~L1983-2080 | main.cpp (auth) |
| handleResetSendCode | main.cpp ~L2080-2170 | main.cpp (auth) |
| handleResetPassword | main.cpp ~L2170-2308 | main.cpp (auth) |
| handleCaptcha / handleCaptchaImage | main.cpp ~L1158,1845-1890 | CaptchaService.hpp |
| RateLimiter 实例(8 个) | main.cpp L417-427 | RateLimiter.hpp |
| CAPTCHA_STORE | main.cpp L438-499 | CaptchaService.hpp |
| JTI_DENYLIST / USER_VER_MAP | main.cpp L447-465 | AuthService.hpp |
**新增配置**(`confs/configs/auth.ini`):
```ini
[Server]
address = 127.0.0.1
port = 8444
[Token]
keep_time = 3600
refresh_grace_multiplier = 2
max_refresh = 10
[Admin]
users = 1776177662@qq.com;277665039@qq.com;
[Downstream]
db_host = 127.0.0.1
db_port = 8005
captcha_host = 127.0.0.1
captcha_port = 8009
smtp_host = 127.0.0.1
smtp_port = 8008
```
**对外接口**(pymsg TCP 协议 + HTTP 双栈):
| 路由 | 协议 | 说明 |
|------|------|------|
| POST /login | HTTP | 登录(兼容前端直访) |
| POST /register | HTTP | 注册 |
| POST /logout | HTTP | 注销 |
| POST /refresh_token | HTTP | Token 刷新 |
| POST /whoami | HTTP | 身份查询 |
| POST /register/send_code | HTTP | 发送注册验证码 |
| POST /reset/send_code | HTTP | 发送重置验证码 |
| POST /reset_password | HTTP | 重置密码 |
| POST /captcha | HTTP | 生成验证码 |
| GET /captcha/image | HTTP | 验证码图片代理 |
| verify | pymsg | 内部验签(替代 /admin/verify,供 core/dnfs2/gateway 调用) |
| whoami | pymsg | 内部身份查询(供 dnfs2 调用) |
### 阶段二:gateway 瘦身
**目标**:gateway 仅保留反向代理 + WebSocket 代理
**保留内容**:
- `handleProxy`(HTTP 反代 + Token 透传)
- WebSocket 代理路由注册 + `verifyWsAdminToken`(改为调 auth 的 pymsg verify 接口)
- `is_special_header` / `is_safe_target` / `get_cookie_value`
- 配置加载、信号处理、LogC
**删除内容**:
- 所有 auth handler(handleLogin ~ handleResetPassword)
- PBKDF2Hasher / PasswordValidator / TokenInfo / JTI_DENYLIST / USER_VER_MAP
- CAPTCHA 相关代码
- 8 个 RateLimiter 实例(迁移到 auth,auth 路由不再经过 gateway 限流)
- RSA 密钥对生成(`_KEYGEN`,迁移到 auth)
**gateway.ini 精简**:
```ini
[Server]
address = 127.0.0.1
port = 8443
tls = off
[Proxy]
default = http://127.0.0.1:9200
opened = http://127.0.0.1:9200;http://127.0.0.1:8006;http://127.0.0.1:5200;
[Auth]
host = 127.0.0.1
port = 8444
[WsProxy]
routes = /ws/aibox=ws://127.0.0.1:8765;
[CORS]
allowed_origins = https://qsont.me;https://www.qsont.me
```
**认证路由处理方案**(二选一):
- **方案 A(推荐):gateway 代理认证路由**
- gateway 将 `/login`、`/register` 等路径加入代理白名单,Target-Url 自动指向 auth 服务
- 前端请求路径不变:`POST /login` → WAF → gateway → auth
- 优势:前端零改动,gateway 仍是唯一入口
- **方案 B:auth 直暴露**
- WAF 配置分流规则,认证路径直接转发到 auth:8444
- 需改动 WAF 配置,增加路由复杂度
### 阶段三:下游服务适配
**目标**:core 和 dnfs2 的验签调用目标从 gateway 切换为 auth
#### 3.1 core 适配
**当前**(`core/src/main/HttpTask.cpp` L155-204):
```cpp
// HTTP POST → gateway:8443/admin/verify
std::string url = "http://" + host + ":" + std::to_string(port) + "/admin/verify";
pmc::net::HttpClient client;
client.set_header("Authorization: " + raw);
client.post_stream_sync(url, "", ...);
```
**改造后**:
```cpp
// pymsg → auth:8444 verify 路由(消除 HTTP 回调,统一内部协议)
pmc::net::MsgClient client(auth_host, auth_port, "core");
json::value req = {{"_route", "verify"}, {"token", raw_token}};
std::string resp = client.call(json::serialize(req), 5.0);
```
#### 3.2 dnfs2 适配
**当前**(`dnfs2/src/dnfs2.cpp` L446-495):
```cpp
// HTTP POST → gateway:8443/whoami
http.post_stream_sync(_cfg.gateway_url, "{}", ...);
```
**改造后**:
```cpp
// pymsg → auth:8444 whoami 路由
RpcClient auth_client(_cfg.auth_host, _cfg.auth_port, "dnfs2", timeout);
json::value result = auth_client.call("whoami", {{"token", token}});
```
**配置文件变更**(`confs/configs/dnfs.ini`):
```ini
[auth] # 新增,替代 [gateway]
host = 127.0.0.1
port = 8444
timeout = 5
```
### 阶段四:启动编排与部署
**core/init.txt 更新**:
```
bash /opt/micro_servers/db2/_run.sh
bash /opt/micro_servers/confs/_run.sh
bash /opt/micro_servers/auth/_run.sh # 新增,须在 gateway 之前启动
bash /opt/micro_servers/ai_review/_run.sh
bash /opt/micro_servers/dnfs2/_run.sh
bash /opt/micro_servers/smtp/_run.sh
bash /opt/micro_servers/static/_run.sh
bash /opt/micro_servers/waf/_run.sh
bash /opt/micro_servers/gateway/_run.sh
bash /opt/micro_servers/captcha/_run.sh
bash /opt/micro_servers/aibox/_run.sh
bash /opt/micro_servers/redirect80/_run.sh
```
**docker-compose.yml 新增 auth 服务**:
```yaml
auth:
build:
context: .
dockerfile: auth/Dockerfile
container_name: micro-auth
ports:
- "127.0.0.1:8444:8444"
environment:
- LISTEN_ADDR=0.0.0.0
- LISTEN_PORT=8444
- DB_HOST=db
- DB_PORT=8005
depends_on:
db:
condition: service_healthy
```
---
## 四、接口契约设计
### 4.1 auth 内部 pymsg 接口(供其他微服务调用)
#### verify 路由(替代 /admin/verify)
```json
// 请求
{"_route": "verify", "token": "base64payload_signature", "require_admin": true}
// 响应(成功)
{"success": true, "user": "admin@example.com", "is_admin": true}
// 响应(失败)
{"success": false, "error": "token expired"}
```
#### whoami 路由(替代 /whoami)
```json
// 请求
{"_route": "whoami", "token": "base64payload_signature"}
// 响应(已登录)
{"success": true, "login": true, "user": "user@example.com", "is_admin": false}
// 响应(未登录/Token 无效)
{"success": true, "login": false}
```
### 4.2 Token 格式不变
保持现有 `Base64(payload)_RSA-Sign(payload)` 格式,payload 字段不变:
```json
{
"user": "email@example.com",
"jti": "random_hex_32",
"ver": 1,
"iat": "2026-08-08 12:00:00",
"created_at": "2026-08-08 12:00:00",
"keep_time": 3600,
"is_admin": true,
"refresh_count": 0,
"max_refresh": 10
}
```
---
## 五、风险评估与缓解
| 风险 | 影响 | 缓解措施 |
|------|------|---------|
| auth 服务不可用导致全系统鉴权失败 | 高 | auth 的 pymsg 客户端启用 `retry_on_refused`;gateway 对 auth 路由的代理失败返回 503(而非静默放行) |
| 前端请求路径变化 | 中 | 采用方案 A(gateway 代理认证路由),前端零改动 |
| Token 验签增加一跳网络延迟 | 低 | pymsg TCP 本机通信延迟 <1ms;gateway 代理层可增加 Token 缓存(TTL 60s) |
| RSA 密钥迁移 | 中 | auth 启动时自生成密钥对(与当前 gateway 行为一致);过渡期可共享密钥文件 |
| 过渡期双系统并存 | 中 | 分阶段切换:先 auth 上线 → gateway 认证路由代理到 auth → 删除 gateway 内置 auth 代码 |
| Token 黑名单持久化需求 | 低 | 初期保持纯内存方案(与现状一致);后续可选 Redis 持久化 |
---
## 六、时间估算
| 阶段 | 工作量 | 说明 |
|------|--------|------|
| 阶段一:auth 服务搭建 | 2-3 天 | 代码迁移 + 新配置 + 测试 |
| 阶段二:gateway 瘦身 | 1 天 | 删除代码 + 代理路由配置 + 回归测试 |
| 阶段三:下游适配 | 1 天 | core/dnfs2 验签调用改造 + 集成测试 |
| 阶段四:部署编排 | 0.5 天 | init.txt + docker-compose + 端到端测试 |
| **合计** | **4.5-5.5 天** | 含测试缓冲 |
---
## 七、验收标准
1. auth 服务独立启动,通过 pymsg 和 HTTP 双栈提供全部认证接口
2. gateway 代码量从 ~2500 行降至 ~800 行,仅含代理逻辑
3. 前端所有认证操作(登录/注册/注销/刷新/重置密码)路径不变、行为不变
4. core/dnfs2 通过 pymsg 调用 auth 验签,延迟 ≤ 5ms(本机)
5. auth 服务重启不影响 gateway 代理转发(已认证请求在 Token 过期前仍有效)
6. 所有现有安全特性(PBKDF2、RSA 签名、常数时间比较、jti 黑名单、版本号吊销)完整保留