easyai-ai-gateway/docs/oidc-jit-provisioning.md
chengcheng 5b8178b703 docs(identity): 记录统一认证恢复与重配边界
补充管理员从 Active 禁用到新接入码重配的标准流程,说明 credentials_saved 恢复、SSF 凭据交接、持久清理、Break-glass 与动态 Origin 边界,并明确历史 Revision 仅作审计、当前不支持直接回滚。
2026-07-17 18:32:04 +08:00

6.2 KiB
Raw Blame History

Auth Center OIDC 用户受控 JIT 预配

适用边界

Gateway 只在 OIDC Token 已通过签名、Issuer、Audience、有效期、tid、Scope 和应用角色校验后执行 JIT。认证中心的稳定 sub 是外部用户标识Gateway 不读取、不保存或公开 Keycloak 内部 ID也不向 Token 增加 gatewayUserId

本次保持单 Gateway 租户:管理员在统一认证 Draft 中把 Auth Center 的已验证 tid 显式绑定到一个已存在、启用且配置了启用中默认用户组的 Gateway 租户。Token 不能创建租户。

配置

OIDC、JIT 和浏览器会话不读取业务环境变量。管理员在 Auth Center 的通用“应用接入”向导选择 OIDC 登录API 验证,生成一次性接入码;再到 Gateway“系统设置 → 统一认证”提交认证中心地址、接入码、Gateway API/Web 地址和本地租户映射。系统自动推导回调及退出地址,生成 Session 加密密钥并保存到部署级 SecretStore。

  • JIT、Legacy JWT 兼容和 Session 时限属于 Revision 策略,可在 Draft 中修改;默认闲置 30 分钟、绝对 8 小时、提前 60 秒刷新。
  • JIT 关闭时停止创建新用户,但已有 source=oidc + external_user_id=sub 映射仍会解析和同步登录时间。
  • 本地租户不存在、公共 Client 不可用或 Discovery/Issuer/JWKS 校验失败时Revision 不能激活,当前 Active Runtime 不受影响。

Web Console 浏览器会话

  • Web 只跳转 GET /api/v1/auth/oidc/login。Gateway 生成 state、nonce、PKCE verifier并以 Authorization Code + PKCE S256 完成换码;公共 Client 请求只发送 client_id,不使用 Client Secret。
  • Access Token、Refresh Token 和 ID Token 使用 AES-256-GCM 加密后存入 PostgreSQL数据库只保存随机 Session Cookie 的 SHA-256。浏览器 JavaScript、响应体和 Web Storage 均不接触 Token。
  • 浏览器只保存 32 字节随机、HttpOnly + SameSite=Strict 的 Session Cookie。新标签页通过该 Cookie 调用 /api/v1/me 恢复登录态Gateway 不签发第二枚 JWT。
  • Access Token 继续保持 5 分钟。认证请求发现剩余时间不超过 60 秒时使用 Refresh Token 自动刷新;多实例通过 PostgreSQL 刷新租约保证同一版本只刷新一次,并原子保存旋转后的 Refresh Token。
  • Session 闲置 30 分钟、绝对最长 8 小时。闲置 530 分钟后的首个请求可自动刷新;超过闲置或绝对期限不会刷新,必须重新登录。浏览器不运行定时刷新。
  • 所有 Web API 请求使用 credentials: include。Cookie 鉴权请求的 Origin 必须与当前健康 Active Revision 的 Gateway Web 地址精确匹配,否则返回结构化 403不接受 *
  • Cookie 的 Secure 属性由 Revision 中的 Gateway API 公网地址推导:生产地址只允许 HTTPS本地开发允许 localhost HTTP。可信 Origin 由 Gateway Web 地址精确推导,不接受 *
  • POST /api/v1/auth/oidc/logout 校验可信 Origin、删除本地 Session、使用公共 Client ID 撤销 Refresh Token并跳转 Auth Center 退出地址;DELETE /api/v1/auth/oidc/session 保留为幂等的本地删除接口。
  • 第一次接入、确认禁用或 Active Runtime 故障恢复时,跨 Origin 管理页面使用部署级精确 bootstrap CORS生产部署建议由反向代理通过同源 /gateway-api 暴露 API。该配置不包含 Issuer、Client 或 Scope。
  • Session Encryption Key 由 Gateway 服务端生成,只以 Secret 引用进入 Revision不得复用 JWT Secret也不会进入数据库、响应、日志或浏览器。禁用统一认证会清理现有 BFF Session重新配对后用户需要重新登录。

数据和事务语义

  • 查找键固定为 source=oidc + external_user_id=subuser_key 由规范化 Issuer 和 sub 做 SHA-256 派生,不按邮箱、手机号、昵称匹配。
  • 首次登录在一个事务中创建 gateway_users 投影、绑定租户默认用户组、初始化 resource 钱包并写入 identity.oidc_user.provisioned 审计事件。
  • 重复或并发登录依赖现有唯一约束和冲突处理返回同一个本地用户,不重复创建钱包或首次预配审计。
  • 后续登录只同步 Token 用户名、应用角色、last_login_atsynced_atsource_updated_at;不覆盖人工资料或用户组,不重新启用已禁用/删除账号。
  • JIT 不生成 API Key 或任何 secret。用户仅在主动创建 API Key 或进入需要 Key 的工作流时触发生命周期操作。

对外错误

所有错误沿用 ErrorEnvelope

HTTP code 含义
403 GATEWAY_USER_NOT_PROVISIONED JIT 关闭且没有已有本地映射
403 GATEWAY_USER_DISABLED 本地用户已禁用或删除
503 GATEWAY_TENANT_UNAVAILABLE 配置租户或用户组不存在/未启用
503 GATEWAY_USER_PROVISIONING_FAILED 事务或存储故障;响应不暴露内部错误
404 OIDC_BROWSER_SESSION_DISABLED Gateway 浏览器会话功能未启用
401 OIDC_SESSION_INVALID Session 不存在、Cookie 格式错误或 Token 身份不匹配
401 OIDC_SESSION_EXPIRED 闲置/绝对期限已到或 Refresh Token 已失效
503 OIDC_SESSION_REFRESH_UNAVAILABLE Access Token 已过期且认证中心暂时不可用
503 OIDC_SESSION_STORE_UNAVAILABLE 数据库或 Token 密文不可用
403 OIDC_SESSION_CSRF_REJECTED Cookie 写请求缺少可信 Origin

ErrLocalUserRequired 仅作为防御性内部错误保留,对外统一转换为结构化 403。

验收与重新接入

自动化门禁通过后,依次验证本地真实 OIDC 和 auth.51easyai.com Staging 专用测试租户。证据应包含脱敏 Claims、网络截图、本地 Gateway 用户记录、Trace ID、Gateway/Auth Center 审计 ID及 200/401/403/503 负向证据;不得保存 Token、授权码、密码或 Secret。

Active Revision 可原位重新验证。需要改变远端身份资源时,先确认本地 Break-glass Manager禁用当前配置再使用 Auth Center 新接入码创建、验证和激活新 Revision历史 superseded Revision 只用于审计,不能直接回滚或重新激活。已经创建的 source=oidc 测试投影保留为惰性数据,不自动删除、迁移或合并。