### 项目概览:统一认证平台 (Unified Authentication Platform - UAP) **核心价值**: * **手机号为主入口**:以手机号作为核心用户标识,支持密码登录,敏感操作(改密)时使用短信验证码。 * **账号映射**:支持将统一认证平台的手机号映射到第三方系统(如老OA)的旧有账号(邮箱、用户名等),解决老系统字段不匹配问题。 * **标准协议支持**:通过集成 Ory Hydra,全面支持 OIDC/OAuth2 协议,使得新应用和开源系统(如 GitLab, Jenkins, Grafana)可以标准、安全地接入。 * **双模接口**:同时提供**OIDC 标准接口**(给新系统)和**简易 API**(给老旧系统),满足混合系统集成需求。 * **安全加固**:集成**原生图形验证码**(`captcha`库),并在敏感操作(如发短信、改密)前强制校验。 * **账号生命周期管理**:通过**Webhook 通知**(FastAPI BackgroundTasks)和**查询接口**,实现用户的新增、变更、停用同步到下游业务系统。 * **应用间信任与跳转**:支持通过“简易 Ticket”机制,实现老旧系统间的无缝跳转。 --- ### 一、 技术选型与架构 * **后端**: * **框架**: FastAPI (Python 3.10+) - 高性能、异步、自动 API 文档。 * **数据库**: MySQL 8.0+ (配合 SQLAlchemy ORM) - 关系型数据存储。 * **缓存/Session**: Redis - 用于存储验证码、Session Cookie、Webhook 任务状态、缓存。 * **AI/CV**: `captcha` 库 (依赖 Pillow) - 生成原生图形验证码。 * **服务器**: Uvicorn (WSGI/ASGI server)。 * **OIDC/OAuth2 核心**: Ory Hydra (部署为独立服务,FastAPI 作为 Login/Consent Provider)。 * **Webhook 推送**: FastAPI `BackgroundTasks` (替代 APScheduler)。 * **前端**: * **框架**: Vue 3 + TypeScript - 现代、高效的 UI 开发。 * **构建工具**: Vite - 极快的冷启动和热更新速度。 * **UI 组件库**: Element Plus - 提供一套完整的后台管理和认证页面组件。 * **部署**: * **API 服务**: FastAPI 应用 (Uvicorn + Gunicorn, Docker)。 * **OIDC 服务**: Ory Hydra (Docker)。 * **前端**: Vue 应用 (Nginx 静态文件服务)。 * **反向代理/负载均衡**: Nginx。 --- ### 二、 核心模块详解 #### 1. 用户管理 (`Users` Table) * **主键**: `id` (Integer, PK) * **核心标识**: `mobile` (String(20), Unique, Index, Not Null) * **安全**: `password_hash` (String(128), Not Null), `salt` (Optional, if not using modern hashes that include salt) * **状态**: `status` (Enum: ACTIVE, DISABLED, Not Null, Default ACTIVE) * **审计**: `created_at`, `updated_at` #### 2. 应用管理 (`Applications` Table) * **主键**: `id` (Integer, PK) * **标识**: `app_id` (String(32), Unique, Index, Not Null) - 分配给第三方系统 * **密钥**: `app_secret_hash` (String(128), Not Null) - 用于接口签名 * **访问令牌**: `access_token` (String(64), Unique) - 永久有效的应用访问令牌,用于 M2M 接口鉴权。 * **信息**: `app_name`, `icon_url` * **协议类型**: `protocol_type` (Enum: OIDC, SIMPLE_API) * **OIDC 配置 (Hydra 对应)**: `redirect_uris` (Text, Not Null - JSON/Array), `grant_types`, `response_types` (Store in Hydra DB, but link via `app_id`) * **Webhook**: `notification_url` (String, Optional) * **审计**: `created_at`, `updated_at` #### 3. 账号映射 (`AppUserMappings` Table) * **主键**: `id` (Integer, PK) * **关联**: `app_id` (FK to Applications), `user_id` (FK to Users) * **核心映射**: `mapped_key` (String(100), Not Null) - 目标系统的账号(邮箱、用户名等) * **状态**: `is_active` (Boolean, Default True) - 映射关系是否启用。 * **唯一性约束**: `UNIQUE(app_id, user_id)` 确保一个用户在同一应用下只映射一次。 * **可选约束**: `UNIQUE(app_id, mapped_key)` (如果目标系统的账号在该应用内必须唯一)。 #### 4. 基础认证 (Auth) * **登录**: * **API (`/api/v1/auth/login`)**: `mobile`, `password`, `app_id` (Optional for direct login). Returns JWT + refresh token. * **H5 Page**: `/page/login` (integrated into UAP). * **OIDC Login**: Redirects to `/auth/login` endpoint, challenge param. * **Token**: JWT for API authentication. Refresh tokens for long-term sessions. * **改密**: * **Hosted Page**: `/page/pwd/reset` (Handles SMS, validation, password update). * **API (`/api/v1/open/sms/send`, `/api/v1/open/pwd/reset`)**: Developers call these to implement their own UI. * `sms/send`: Requires `captcha_id`, `captcha_code`. * `pwd/reset`: Requires `mobile`, `sms_code`, `new_password`, `sign`. #### 5. 验证码 (Captcha) * **技术**: `captcha` Python library + `Pillow`。 * **接口 (`/api/v1/utils/captcha`)**: * `GET`: Generates `captcha_id`, image (Base64), stores code in Redis (key `CAPTCHA:{uuid}`, expiry `settings.CAPTCHA_EXPIRE_SECONDS`). * `POST /sms/send` (and others) **must** call `CaptchaService.verify_captcha(captcha_id, user_input)` *before* proceeding. * `verify_captcha` deletes the key upon success or first attempt (fail-safe). #### 6. 账号映射与导入导出 (Mappings & Import/Export) * **核心逻辑**: `mapped_key` 字段存储映射值。 * **导入/导出**: * **Template Download**: Generate Excel template (`phone`, `mapped_key`, `name`). Use `pandas` or `openpyxl`. * **Preview API (`/api/v1/apps/{app_id}/mapping/preview`)**: 1. Read Excel with `pandas`. 2. Validate `mobile` is not empty. 3. Batch query `Users` table for existence. 4. Batch query `AppUserMappings` table for duplicates. 5. Return JSON with counts (`new`, `duplicate`, `invalid`) and detailed rows with `status`, `reason`. * **Import API (`/api/v1/apps/{app_id}/mapping/import`)**: * Accepts `strategy` (SKIP/OVERWRITE). * Performs batch `INSERT IGNORE` or `ON DUPLICATE KEY UPDATE` using SQLAlchemy. #### 7. OIDC 集成 (Ory Hydra) * **FastAPI 作为 Login/Consent Provider**: * **`/auth/login` endpoint**: Receives `login_challenge` from Hydra. Verifies user credentials (phone+pass) or checks UAP Session Cookie. Calls `hydra.accept_login_request(challenge, subject=user_id)`. * **`/auth/consent` endpoint**: Receives `consent_challenge` from Hydra. Fetches user's mappings for the `client_id` (App ID). Constructs `id_token` claims (e.g., `email`, `preferred_username`) based on `mapped_key`. Calls `hydra.accept_consent_request(challenge, session={"id_token": {...}})`. * **Application Registration**: When an App is created/updated in UAP Admin, a corresponding Client is created/updated in Hydra via its Admin API. #### 8. 账号生命周期同步 (User Provisioning) * **Webhook (Push)**: * FastAPI `BackgroundTasks` triggers `send_webhook_notification`. * Payload includes `event_type` (ADD, UPDATE, DISABLE), `app_id`, `user_data` (mobile, name, mapped_key, status). * Signature `X-UAP-Signature` must be verified by the receiving system. * **Logging**: Failed calls are logged to `WebhookLogs` table. Manual retry option for admins. * **API (Pull - Detail Query & Sync)**: * `POST /api/v1/apps/mapping/sync`: 同步映射关系(新增/更新/停用)。支持 Header `X-App-Access-Token`。 * `GET /api/v1/apps/{app_id}/users/query?mobile={mobile}`: Returns user details and mappings. Used by legacy systems during login if local user not found. * `GET /api/v1/apps/{app_id}/users/changes?since={timestamp}`: Returns a list of changes. Less critical if Webhook is primary. #### 9. 应用间跳转 (Ticket Exchange) * **场景**: System A needs to log user into System B without re-authentication. * **API (`POST /api/v1/simple/ticket/exchange`)**: * **Requires**: `app_id` (source), `target_app_id`, `user_mobile`, `sign`. * **Logic**: Verifies source `app_id`/`sign`. Looks up mapping for `target_app_id` and `user_mobile`. Generates a short-lived `Ticket_B`. Returns `redirect_url` (`target_app_url/callback?ticket=TICKET_B`). * **SSO Cookie Enhancement**: If user already has UAP `AUTH_SESSION_ID` cookie, the redirection logic in `/page/login` (for SIMPLE\_API apps) can directly generate `Ticket_B` without user interaction. #### 10. API 文档 (Swagger UI) * **Backend**: Use FastAPI's automatic OpenAPI generation. * Tag endpoints clearly: `tags=["Admin"]` vs `tags=["OpenAPI"]`, `tags=["SimpleAuth"]`. * Customize `/docs/admin` (all routes) and `/docs/open` (filtered routes) using `get_openapi` and `get_swagger_ui_html`. * Enrich descriptions with Markdown, Pydantic `Field` descriptions, `summary`. * **Frontend**: Embed `/docs/open` into a Vue page using `