Files
jczxw-java/iam-api/docs/iam-api-dev-plan.md
T
gxwebsoft 5e86ebe6b7 feat(auth): 实现统一认证模块及登录策略
- 新增 ApiResult 统一响应封装类,规范前端接口返回结构
- 添加 AuthController,支持多种登录方式及用户信息接口
- 实现 AuthService,包含登录、登出、密码修改、绑定手机号、重置密码等功能
- 集成图形验证码校验和登录失败锁定机制,增强安全性
- 支持邮箱登录和手机号验证码登录,完善多样化认证策略
- 实现 JWT 令牌签发与吊销,确保会话安全管理
- 配置不同环境 application.yml 及配置,支持多租户和灵活缓存配置
- 增加 .gitignore 规则,屏蔽构建产物、IDE 文件和敏感配置
- 引入 AuthProperties 以配置登录与验证码策略参数
2026-09-23 11:59:45 +08:00

146 lines
8.0 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.
# iam-api 开发计划
> 统一身份中心(Identity & Access Management)。目标:把「用户 / 租户 / 角色 / 权限 /
> 菜单 / 登录 / 令牌签发」从 `open-api` 里抽出来,成为 `open-api` 与 `dp-api` 共用的
> 唯一账号源,使 `dp-api` 可以脱离 `open-api` 独立售卖与部署。
## 1. 定位与边界
### 1.1 iam-api 负责
| 能力 | 说明 |
|---|---|
| 身份(Identity) | 租户、用户、账号密码 / 邮箱 / 手机号、密码强度与找回、绑定手机 |
| 授权(Access) | 角色、权限标识、菜单(菜单即权限载体)、用户-角色-菜单关系 |
| 会话(Session) | 控制台登录态令牌(HS256)、登出吊销、登录失败锁定、登录审计 |
| 令牌(Token) | 面向资源服务的 RS256 access token、refresh token、JWKS、introspect、revoke |
| 客户端(Client) | `iam_client` 注册表:登记 open-api / dp-api 等消费方及其允许的 scope / aud |
### 1.2 iam-api 不负责
- 开放平台的业务语义:应用管理、OAuth2 授权页、scope 字典、令牌签发统计(留在 `open-api`)。
- 数据中台的业务数据:服务器、客户、订单、合同、发票、支付(留在 `dp-api`)。
- 通用底座:云存储、系统设置、字典、附件、消息、审计(后续放 `base-api`)。
> 边界一句话:**iam-api 只知道“你是谁、你能干什么”,不知道“你干的是什么业务”。**
### 1.3 与 open-api / dp-api 的关系
```
┌──────────────────────────────┐
│ iam-api │
│ 账号/租户/角色/权限/菜单/令牌 │
└───────────┬──────────────────┘
RS256 令牌 + JWKS │ RS256 令牌 + JWKS
┌─────────────────────┴─────────────────────┐
▼ ▼
┌─────────────┐ ┌─────────────┐
│ open-api │ │ dp-api │
│ 开放平台 │ │ 数据中台 │
└─────────────┘ └─────────────┘
```
- 两个资源服务都只通过 JWKS 验签,不共享用户表、不共享对称密钥。
- 同一个 `user_id` 可以在两个产品里拥有不同角色:
`iam_user_role` 带 `client_id`(为空表示控制台全局角色),授权按消费者隔离。
## 2. 里程碑
### M1 内核与骨架(本期)
- [x] Maven 工程、Spring Boot 3.5 / Java 25、Flyway、MyBatis-Plus
- [x] 统一返回结构、全局异常、分页与查询参数封装
- [x] 多租户上下文与 MyBatis-Plus 租户插件
- [x] 缓存抽象 `CacheStore`(Redis / 内存双实现,演示与测试免 Redis)
### M2 身份与授权(本期)
- [x] `sys_tenant` / `sys_user` / `sys_role` / `sys_menu` / 关联表 / 登录审计
- [x] 租户、用户、角色、菜单的查询与管理接口
- [x] 用户带角色与权限集合,供控制台做按钮级权限
### M3 登录与安全(本期)
- [x] 账号密码登录(图形验证码 + 失败锁定)
- [x] 邮箱登录、手机号验证码登录
- [x] 登出(令牌吊销)、`/api/me`、修改密码、绑定/换绑手机号、自助找回密码
- [x] HS256 会话令牌 + 认证过滤器 + 401/403 统一处理
### M4 统一令牌与客户端(本期)
- [x] `iam_client` 客户端注册表与 scope 白名单
- [x] RS256 令牌签发:`client_credentials` / `authorization_code(PKCE)` / `refresh_token`
- [x] `/api/v1/oauth/jwks` 公钥集合、`/api/v1/oauth/introspect`、`/api/v1/oauth/revoke`
- [x] 授权码存储与一次性核销(`iam_auth_code`)
### M5 迁出与联调(下一期)
- [ ] open-api 改为 iam-api 的客户端:登录跳转/代理、用户信息改读 iam-api
- [ ] dp-api 接入:JWKS 验签 + `tenant_id` / 角色映射
- [ ] 存量用户迁移脚本(`db_open.sys_user` → `iam_user`)与双写过渡
- [ ] 平台运营端(账号开通、跨租户管理)迁到 iam-api 或独立的 iam-admin
### M6 单点登录与合规(远期)
- [ ] SSO 会话表 `iam_sso_session` 与跨域免登票据
- [ ] MFA(TOTP)、登录设备管理、异常登录提醒
- [ ] 审计中心:把登录审计升级为操作审计
## 3. 数据模型
| 表 | 说明 |
|---|---|
| `sys_tenant` | 租户 |
| `sys_user` | 用户(BCrypt 密码,邮箱/手机号可空) |
| `sys_role` | 角色 |
| `sys_user_role` | 用户-角色 |
| `sys_menu` | 菜单 / 权限点 |
| `sys_role_menu` | 角色-菜单 |
| `sys_login_record` | 登录审计 |
| `iam_client` | 接入方(client_id / secret / 允许 scope / 令牌有效期) |
| `iam_auth_code` | OAuth2 授权码(一次性、短有效期) |
所有业务表统一:`del_flag` 逻辑删除、`create_time` / `update_time` 应用层填充。
## 4. 接口一览(本期)
| 分组 | 接口 |
|---|---|
| 认证 | `POST /api/login`、`POST /api/loginByEmail`、`POST /api/loginBySms`、`POST /api/logout`、`GET /api/me`、`POST /api/changePassword`、`POST /api/resetPassword`、`POST /api/bindPhone`、`POST /api/bindPhone/captcha` |
| 验证码 | `GET /api/captcha`、`POST /api/sendSmsCaptcha`、`POST /api/sendEmailCaptcha` |
| 租户 | `GET/POST/PUT/DELETE /api/iam/tenant`、`GET /api/iam/tenant/{id}` |
| 用户 | `GET /api/iam/user`、`POST /api/iam/user`、`PUT /api/iam/user/{id}`、`DELETE /api/iam/user/{id}`、`POST /api/iam/user/{id}/resetPassword` |
| 角色 | `GET /api/iam/role`、`POST /api/iam/role`、`PUT /api/iam/role/{id}`、`DELETE /api/iam/role/{id}`、`PUT /api/iam/role/{id}/menus` |
| 菜单 | `GET /api/iam/menu/tree`、`POST /api/iam/menu`、`PUT /api/iam/menu/{id}`、`DELETE /api/iam/menu/{id}` |
| 客户端 | `GET /api/iam/client`、`POST /api/iam/client`、`PUT /api/iam/client/{id}`、`DELETE /api/iam/client/{id}`、`POST /api/iam/client/{id}/secret` |
| 令牌 | `POST /api/v1/oauth/token`、`GET /api/v1/oauth/jwks`、`POST /api/v1/oauth/introspect`、`POST /api/v1/oauth/revoke` |
## 5. 配置
| 配置项 | 说明 | 默认 |
|---|---|---|
| `server.port` | 服务端口 | `8900` |
| `iam.cache.type` | 缓存实现:`redis` / `memory` | `redis`(`demo`/`test` 为 `memory`) |
| `config.jwt.secret` | 控制台会话令牌密钥(HS256) | 开发默认值,生产必须覆盖 |
| `config.iam-jwt.private-key` | 资源服务令牌私钥(RS256,PEM) | 缺省时启动生成临时密钥并告警 |
| `config.internal-key` | introspect 调用方自证密钥 | `change-me` |
## 6. 部署
- 端口 `8900`,与 `open-api`(8800) / `dp-api`(18800) 并存。
- 生产用 Docker(`Dockerfile` + `docker-compose.yml`),MySQL + Redis 由编排提供。
- 演示与测试走 `-Pdemo` / `test` profile,H2 + 内存缓存,无外部依赖。
- Flyway 用**独立迁移账号**(`FLYWAY_USER` / `FLYWAY_PASSWORD`),与业务账号分离:
Flyway 建连接时要读 `performance_schema.user_variables_by_thread`,业务账号不该为此扩权。
建号脚本 `scripts/create-flyway-user.sql`;无法授权时用 `scripts/apply-migrations.sh` 手工迁移。
## 7. 风险与对策
| 风险 | 对策 |
|---|---|
| 双用户表导致身份漂移 | 迁移期以 iam-api 为准,open-api / dp-api 只读;禁止双向写 |
| 令牌吊销的传播延迟 | access token 短有效期(默认 2h)+ 资源服务就近校验 + introspect 兜底 |
| Redis 不可用导致全员无法登录 | `CacheStore` 降级策略与 `iam.cache.type` 显式切换,健康检查暴露状态 |
| 认证与业务耦合 | 资源服务只依赖 JWKS 公钥,不引入 iam-api 的代码依赖 |
| 迁移账号权限不足导致启动失败 | Flyway 独立账号 + 建号脚本;退路是关闭 Flyway 用 `scripts/apply-migrations.sh` |