Files
Hugo/4a-system-design/auth-identity-center.md
T

18 KiB
Raw Blame History

认证身份中心设计

1. 总体定位

认证身份中心是4A系统的统一认证入口和账号数据基座,合并了传统4A中"认证"和"身份"两个模块。核心职责:

  • 维护全平台统一的账号数据模型
  • 提供多因素认证能力(密码 + 人脸 + SIM卡识别 + 短信验证码)
  • 管理用户会话和令牌(JWT签发/验证/刷新)
  • 与现网账号平台保持账号数据实时/准实时一致

2. 数据模型

2.1 核心账号表(T_ACCOUNT)

-- 账号主表
CREATE TABLE T_ACCOUNT (
    account_id          BIGINT       PRIMARY KEY AUTO_INCREMENT,
    -- 统一账号标识(与现网账号平台对齐)
    uid                 VARCHAR(64)  NOT NULL UNIQUE COMMENT '统一用户ID,与现网平台一致',
    login_name          VARCHAR(128) NOT NULL UNIQUE COMMENT '登录名',
    display_name        VARCHAR(256)          COMMENT '显示姓名',
    -- 身份信息
    id_type             TINYINT      NOT NULL DEFAULT 1 COMMENT '身份类型:1-内部员工 2-外包 3-第三方 4-临时',
    employee_id         VARCHAR(64)           COMMENT '工号',
    org_code            VARCHAR(64)           COMMENT '所属组织编码',
    org_path            VARCHAR(512)          COMMENT '组织全路径, 如:省公司/市公司/部门',
    -- 联系方式
    mobile              VARCHAR(32)           COMMENT '手机号',
    email               VARCHAR(256)          COMMENT '邮箱',
    -- 认证凭据
    password_hash       VARCHAR(256)          COMMENT '密码哈希(BCrypt)',
    password_salt       VARCHAR(64)           COMMENT '密码盐值',
    password_version    INT         NOT NULL DEFAULT 1 COMMENT '密码策略版本号',
    need_reset_password TINYINT     NOT NULL DEFAULT 0 COMMENT '需要重置密码:0-否 1-是',
    -- 人脸信息
    face_template_id    VARCHAR(128)          COMMENT '人脸模板ID(金科侧)',
    face_registered     TINYINT     NOT NULL DEFAULT 0 COMMENT '是否已注册人脸',
    -- SIM卡信息
    sim_imsi            VARCHAR(64)           COMMENT 'SIM卡IMSI(互联网SIM卡识别用)',
    sim_phone           VARCHAR(32)           COMMENT 'SIM卡关联手机号',
    sim_verified        TINYINT     NOT NULL DEFAULT 0 COMMENT 'SIM卡是否已验证',
    -- 状态管理
    status              TINYINT     NOT NULL DEFAULT 1 COMMENT '状态:0-禁用 1-正常 2-锁定 3-过期',
    lock_reason         VARCHAR(256)          COMMENT '锁定原因',
    last_login_ip       VARCHAR(64)           COMMENT '最后登录IP',
    last_login_time     DATETIME              COMMENT '最后登录时间',
    login_fail_count    INT         NOT NULL DEFAULT 0 COMMENT '连续登录失败次数',
    unlock_time         DATETIME              COMMENT '自动解锁时间',
    -- 有效期
    effective_date      DATE                  COMMENT '生效日期',
    expire_date         DATE                  COMMENT '失效日期',
    -- 审计字段
    created_by          VARCHAR(64)  NOT NULL,
    created_at          DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_by          VARCHAR(64)  NOT NULL,
    updated_at          DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    version             INT          NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
    deleted             TINYINT      NOT NULL DEFAULT 0 COMMENT '逻辑删除:0-未删除 1-已删除',

    INDEX idx_uid (uid),
    INDEX idx_login_name (login_name),
    INDEX idx_org_code (org_code),
    INDEX idx_mobile (mobile),
    INDEX idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='账号主表';

2.2 账号扩展属性表(T_ACCOUNT_ATTR)

支持与现网平台扩展属性的灵活映射,避免频繁改表。

CREATE TABLE T_ACCOUNT_ATTR (
    id          BIGINT       PRIMARY KEY AUTO_INCREMENT,
    account_id  BIGINT       NOT NULL COMMENT '关联账号ID',
    attr_key    VARCHAR(128) NOT NULL COMMENT '属性键',
    attr_value  VARCHAR(1024)         COMMENT '属性值',
    attr_type   VARCHAR(32)           COMMENT '值类型:string/number/date/json',
    created_at  DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at  DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

    UNIQUE KEY uk_account_attr (account_id, attr_key),
    INDEX idx_attr_key (attr_key, attr_value(128))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='账号扩展属性表';

2.3 与现网账号平台拉齐方案

现网账号平台通常是多系统异构的(HR系统、OA、运维平台等各有账号体系)。拉齐策略:

┌─────────────────────────────────────────────────────────────────┐
│                    现网账号平台(多源)                           │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────────┐   │
│  │ HR系统    │  │ OA系统    │  │ 运维平台  │  │ 第三方接入   │   │
│  │ (工号为主)│  │(邮箱为主) │  │ (SSH用户) │  │ (API对接)   │   │
│  └─────┬────┘  └────┬─────┘  └─────┬────┘  └──────┬───────┘   │
│        │            │             │              │            │
│        └──────┬─────┴──────┬──────┴──────────────┘            │
│               │            │                                  │
│        ┌──────▼────────────▼──────┐                           │
│        │    账号同步适配器层       │                           │
│        │  (定时拉取 + 变更推送)    │                           │
│        │  策略:现网→自研单向同步   │                           │
│        │  冲突:以现网最新时间为准   │                           │
│        └───────────┬──────────────┘                           │
│                    │                                          │
│        ┌───────────▼──────────────┐                           │
│        │   自研T_ACCOUNT主表       │                           │
│        │   (以uid为统一标识)       │                           │
│        │   额外字段:sync_source   │                           │
│        │   sync_version           │                           │
│        └──────────────────────────┘                           │
└─────────────────────────────────────────────────────────────────┘

同步策略关键点:

  1. 单向同步:现网平台 → 自研系统(防止自研的修改反向污染现网)
  2. 标识统一:uid 字段作为跨系统唯一标识,映射现网各系统 ID
  3. 定时+事件驱动:
    • 定时全量同步(每天凌晨)
    • 变更事件订阅(MQ消息,实时增量同步)
    • 手动触发全量同步(管理员操作)
  4. 冲突处理:
    • 自研系统只读现网字段,不做覆盖
    • 现网字段为主版本,自研扩展字段(如人脸模板ID)为从版本
    • 时间戳精度到毫秒级,解决并发冲突
  5. 挂载表记录同步日志:T_ACCOUNT_SYNC_LOG 记录每次同步的变更明细

3. 认证能力接入

3.1 认证流程总图

                           ┌──────────────────────┐
                           │  统一认证入口          │
                           │  POST /api/v1/auth    │
                           └──────────┬───────────┘
                                      │
                    ┌─────────────────┼─────────────────┐
                    │                 │                 │
              ┌─────▼─────┐   ┌──────▼──────┐   ┌──────▼──────┐
              │ 密码认证    │   │  人脸认证    │   │  SIM认证     │
              │ provider   │   │  provider   │   │  provider   │
              └─────┬─────┘   └──────┬──────┘   └──────┬──────┘
                    │                 │                 │
                    └────────┬────────┴────────┬────────┘
                             │                  │
                      ┌──────▼──────┐    ┌──────▼──────┐
                      │ 认证成功     │    │ 认证失败     │
                      │ → 生成令牌   │    │ → 记录失败   │
                      │ → 返回JWT   │    │ → 触发告警   │
                      └─────────────┘    └─────────────┘

3.2 密码认证

  • 技术选型:BCrypt(自适应哈希,cost factor=10-12)
  • 策略:
    • 支持密码复杂度策略(长度/大小写/特殊字符组合)
    • 支持密码历史管理(禁止使用最近N次密码)
    • 连续失败N次后锁定账号 T 分钟
    • 支持首次登录强制改密
  • 接口:标准 OAuth2 Password Grant + 自定义扩展

3.3 金科人脸识别接入

集成方案:

# 金科人脸识别对接配置
face_recognition:
  provider: "jinke"
  api_base: "https://face-api.chinamobile.com/v2"
  auth_mode: "aksk"                    # API Key + Secret Key 认证
  timeout_ms: 5000
  retry:
    max_attempts: 2
    backoff_ms: 200
  endpoints:
    verify: "/face/verify"             # 1:1 人脸验证
    detect: "/face/detect"             # 人脸检测
    register: "/face/register"         # 人脸模板注册
    delete: "/face/template/delete"    # 删除人脸模板
  liveness:
    enabled: true                      # 活体检测开关
    mode: "action"                     # action: 动作指令式, flash: 闪光

认证流程:

  1. 客户端采集人脸图片 → 上传至自研后台
  2. 自研后台调用金科 /face/detect 检测有效性(活体检测)
  3. 通过后调用 /face/verify 传入用户 uid + 人脸图片
  4. 金科返回置信度和匹配结果(阈值 >= 0.85 视为通过)
  5. 自研后台记录认证日志,签发JWT

3.4 互联网SIM卡识别

能力说明:

  • 利用运营商网关能力,识别用户手机号与SIM卡IMSI的绑定关系
  • 用户通过蜂窝网络访问时,网关可携带SIM卡信息
  • 实现"无感认证"——用户只需打开页面即可自动识别身份

接入方案:

用户手机(蜂窝网络) ──→ 运营商网关 ──→ 自研4A网关
                    ↑                ↑
               HTTP Header携带    解析Header提取
               IMSI/MSISDN       SIM信息,与账号
                                T_ACCOUNT.sim_imsi
                                做匹配验证

技术要点:

  1. 依赖运营商网关配置(需与网络部协调开通)
  2. 作为辅助认证因子,不可单独作为强认证手段
  3. 需配合设备指纹、IP地理位置等信息做风险判断
  4. 当SIM信息与预注册信息不一致时,触发二次认证(短信验证码)

3.5 消息中心短信接入

集成方案:

sms:
  provider: "message_center"           # 中国移动消息中心
  api_base: "https://msg-center.chinamobile.com/api"
  app_id: "${SMS_APP_ID}"
  app_secret: "${SMS_APP_SECRET}"
  endpoints:
    send: "/sms/send"
    batch_send: "/sms/batch_send"
    query_status: "/sms/status/{msg_id}"
  features:
    template: true                     # 使用短信模板(防篡改)
    signature: "【中国移动】"
    expiry_minutes: 5                  # 验证码有效期5分钟

流程:

  1. 发送验证码:生成6位数字验证码 → 写入 Redis(key=sms:code:{mobile}, TTL=300s)→ 调用消息中心API下发
  2. 验证:用户提交验证码 → 查 Redis 比对 → 正确则完成认证
  3. 限制策略:60秒内不可重复发送,每日上限10次

3.6 多因素认证组合策略

┌──────────────────────────────────────────────────────────────────┐
│  MFA策略配置(可动态调整)                                        │
│                                                                  │
│  场景类型          │ 认证因子组合                                 │
│  ──────────────────┼───────────────────────────────────────────  │
│  内部网络登录       │ 密码                    (单因素)            │
│  远程VPN登录       │ 密码 + 短信验证码        (双因素)            │
│  堡垒机登录        │ 密码 + 人脸/SIM         (双因素)            │
│  敏感操作确认       │ 已登录令牌 + 短信验证码  (双因素)            │
│  管理员操作        │ 密码 + 人脸 + 短信验证码  (三因素)            │
│  SIM卡网关识别     │ SIM识别                  (零操作)            │
└──────────────────────────────────────────────────────────────────┘

4. 令牌与会话管理

4.1 JWT令牌设计

{
  "access_token": {
    "header": {"alg": "RS256", "typ": "JWT", "kid": "2026-01"},
    "payload": {
      "sub": "uid_00123",
      "iss": "4a-self",
      "aud": "4a-resource-centers",
      "exp": 3600,
      "iat": 1700000000,
      "jti": "unique-token-id-abc123",
      "auth_context": {
        "mfa_level": 2,
        "auth_methods": ["password", "sms"],
        "session_id": "sess_xyz789"
      },
      "roles": ["operator", "auditor"]
    },
    "sign": "RS256_signature..."
  },
  "refresh_token": {
    "expiry": 86400 * 7,
    "rotation": true
  }
}
  • 签名算法:RS256(非对称),access_token 和 refresh_token 使用不同密钥对
  • 有效期:access_token 1小时,refresh_token 7天(支持滑动刷新)
  • 吊销机制:Redis 维护黑名单(jti:revoked),注销/改密后立即使所有token失效

4.2 会话状态存储

Redis Key 设计:
  4a:session:{session_id}   → Session对象(用户信息、MFA等级、设备指纹)
  4a:token:jti:{jti}        → 令牌元数据(issuer_ip、issued_at、status)
  4a:token:user:{uid}       → 用户当前有效令牌列表
  4a:token:blacklist:{jti}  → 吊销令牌集合(TTL = token有效期)
  4a:sms:code:{mobile}      → 短信验证码(TTL = 300s)
  4a:login:fail:{uid}       → 登录失败计数(TTL = 锁定周期)

5. 接口规范

5.1 认证接口

接口 方法 说明
/api/v1/auth/login POST 统一登录入口,请求体指定认证方式
/api/v1/auth/refresh POST 刷新access_token
/api/v1/auth/logout POST 登出,吊销令牌
/api/v1/auth/check GET 校验令牌有效性
/api/v1/auth/sms/send POST 发送短信验证码
/api/v1/auth/face/register POST 注册人脸模板
/api/v1/auth/sim/verify POST SIM卡验证

5.2 账号管理接口

接口 方法 说明
/api/v1/accounts GET 分页查询账号列表
/api/v1/accounts/{uid} GET 查询单个账号详情
/api/v1/accounts POST 创建账号(同步到现网需审批)
/api/v1/accounts/{uid} PUT 更新账号信息
/api/v1/accounts/{uid} DELETE 禁用/删除账号
/api/v1/accounts/{uid}/password PUT 修改密码
/api/v1/accounts/{uid}/status PATCH 修改账号状态
/api/v1/accounts/sync/trigger POST 手动触发全量同步
/api/v1/accounts/sync/log GET 查询同步日志

5.3 响应格式

// 成功响应
{
  "code": 0,
  "message": "success",
  "data": {},
  "request_id": "req-uuid-xxx"
}

// 错误响应
{
  "code": 40101,
  "message": "invalid_credentials",
  "detail": "密码错误,还剩3次尝试机会",
  "request_id": "req-uuid-xxx"
}

6. 与泰岳版比对关注点

项 自研方案 泰岳方案(推测) 验证方法
密码存储 BCrypt + 多代盐值 厂商自研加密模块 黑盒:记录认证耗时
会话管理 Redis + JWT 可能为DB + Session 比较并发下Session创建吞吐
认证流程扩展 Provider模式,可插拔 模块化程度未知 接入新因子时的改动量对比
多因素组合 策略引擎(DSL配置) 可能硬编码 配置灵活度对比
账号同步 适配器模式对接多源 可能单源集中 同步延迟和完整性对比