Files
iam-service/README.md
2026-01-31 11:11:55 +08:00

231 lines
7.9 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-service多租户 IAM 服务)
一个基于 Rust 的多租户身份识别与访问管理IAM服务雏形当前已提供“租户隔离 + 用户注册/登录 + 基础租户管理 + 基于 JWT 的认证中间件 + RBAC 权限校验骨架”能力,并为后续扩展 MFA/SSO、Token 刷新/吊销、ABAC 策略引擎等功能预留了模块边界。
## 技术栈
- 语言与运行时Rustedition 2024、Tokio
- WebAxum
- 数据库PostgreSQL + SQLx
- 密码Argon2
- TokenJWTRS256 非对称签发/验签已实现JWK Set 端点待补齐)
- 可观测性tracing + `common-telemetry`(私有 registrykellnr
- API 文档utoipa + Scalar`/scalar`
## 系统架构
### 请求链路(当前)
```mermaid
flowchart LR
C[Client] -->|HTTP + JSON| R[Axum Router]
R --> A[认证中间件 authenticate]
A --> M[租户中间件 resolve_tenant]
M --> H[Handlers + RBAC 校验]
H --> S[Services]
S --> DB[(PostgreSQL)]
H --> O[统一错误 AppError]
R --> D[OpenAPI/Scalar /scalar]
```
### 多租户实现方式
当前采用“共享数据库 + 共享表,通过 `tenant_id` 区分”的模式:
- `users.tenant_id` 外键引用 `tenants.id`(强制用户必须归属某个租户)
- `users(tenant_id, email)` 联合唯一索引(同租户邮箱唯一,不同租户可重复)
- HTTP 层优先通过 `Authorization: Bearer <access_token>` 中的 `tenant_id` claim 传入租户上下文,并在 Service/SQL 查询中使用 `tenant_id` 过滤
- 兼容:仍支持请求头 `X-Tenant-ID: <uuid>`,若同时提供 Header 与 Token将强制校验两者一致否则返回 403
## 项目结构说明
- [src/main.rs](file:///home/shay/project/backend/iam-service/src/main.rs)服务入口、路由组装、Telemetry 初始化、DB 连接池初始化
- [src/config/mod.rs](file:///home/shay/project/backend/iam-service/src/config/mod.rs):环境变量配置加载
- [src/db/mod.rs](file:///home/shay/project/backend/iam-service/src/db/mod.rs)PostgreSQL 连接池初始化(迁移功能目前未启用)
- [src/middleware/mod.rs](file:///home/shay/project/backend/iam-service/src/middleware/mod.rs):多租户中间件与 `TenantId` 提取器
- [src/middleware/auth.rs](file:///home/shay/project/backend/iam-service/src/middleware/auth.rs)JWT 认证中间件与 `AuthContext` 提取器
- [src/handlers/mod.rs](file:///home/shay/project/backend/iam-service/src/handlers/mod.rs)HTTP Handler控制器层负责参数解析、调用 Service、返回统一响应
- [src/services/mod.rs](file:///home/shay/project/backend/iam-service/src/services/mod.rs):业务逻辑(注册/登录)与数据库交互
- [src/models.rs](file:///home/shay/project/backend/iam-service/src/models.rs)DB Model 与请求/响应 DTO同时用于 OpenAPI Schema
- [src/utils/mod.rs](file:///home/shay/project/backend/iam-service/src/utils/mod.rs):密码哈希与 JWT 签发工具
- [scripts/db/README.md](file:///home/shay/project/backend/iam-service/scripts/db/README.md):数据库迁移/校验/回滚说明(开发/测试/生产)
- [scripts/db/rebuild_iam_db.sh](file:///home/shay/project/backend/iam-service/scripts/db/rebuild_iam_db.sh):开发用一键重建(会清库重建+迁移+校验,不适合生产)
## 快速开始
### 环境要求
- Rust支持 edition 2024 的版本(建议使用最新 stable
- PostgreSQL建议 14+
### 安装与运行
1. 克隆仓库并进入目录
```bash
git clone <your-repo-url>
cd iam-service
```
2. 初始化数据库(开发/测试示例)
```bash
export DATABASE_URL='postgres://iam_service_user:***@<pg_host>:5432/iam_service_db'
BACKUP=1 ./scripts/db/rebuild_iam_db.sh
```
3. 配置环境变量
```bash
cp .env.example .env
```
按需修改 `.env`
- `DATABASE_URL`PostgreSQL 连接串
- `JWT_SECRET`:保留字段(当前 RS256 实现未使用;后续将用于密钥加载/加密存储)
- `PORT`:监听端口
4. 启动服务
```bash
cargo run
```
启动后:
- 服务地址:`http://127.0.0.1:<PORT>`
- API 文档:`http://127.0.0.1:<PORT>/scalar`
## 核心功能与 API
### 租户注册
`POST /tenants/register`
```bash
curl -X POST "http://127.0.0.1:3000/tenants/register" \
-H "Content-Type: application/json" \
-d '{"name":"Tenant A","config":{"theme":{"primary":"#1d4ed8"}}}'
```
返回(示例):
```json
{
"code": 0,
"message": "Created",
"data": {
"id": "22222222-2222-2222-2222-222222222222",
"name": "Tenant A",
"status": "active",
"config": { "theme": { "primary": "#1d4ed8" } }
},
"trace_id": null
}
```
### 用户注册
`POST /auth/register`(需要请求头 `X-Tenant-ID`
```bash
curl -X POST "http://127.0.0.1:3000/auth/register" \
-H "Content-Type: application/json" \
-H "X-Tenant-ID: 11111111-1111-1111-1111-111111111111" \
-d '{"email":"user@example.com","password":"securePassword123"}'
```
返回(示例):
```json
{
"code": 0,
"message": "Created",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com"
},
"trace_id": null
}
```
### 登录
`POST /auth/login`(需要请求头 `X-Tenant-ID`
```bash
curl -X POST "http://127.0.0.1:3000/auth/login" \
-H "Content-Type: application/json" \
-H "X-Tenant-ID: 11111111-1111-1111-1111-111111111111" \
-d '{"email":"user@example.com","password":"securePassword123"}'
```
返回(示例):
```json
{
"code": 0,
"message": "Success",
"data": {
"access_token": "<jwt>",
"refresh_token": "<opaque>",
"token_type": "Bearer",
"expires_in": 900
},
"trace_id": null
}
```
### 租户信息维护(需要鉴权 + 权限)
- `GET /tenants/me`(需要 `tenant:read`
- `PATCH /tenants/me`(需要 `tenant:write`
- `POST /tenants/me/status`(需要 `tenant:write`
- `DELETE /tenants/me`(需要 `tenant:write`
调用示例:
```bash
curl -X GET "http://127.0.0.1:3000/tenants/me" \
-H "Authorization: Bearer <access_token>"
```
## 权限控制(当前实现方式)
- 认证Authentication在中间件层完成[auth.rs](file:///home/shay/project/backend/iam-service/src/middleware/auth.rs)),统一解析 `Authorization`,验签 JWT并注入 `AuthContext`
- 租户上下文Tenant Context在中间件层完成[mod.rs](file:///home/shay/project/backend/iam-service/src/middleware/mod.rs)),优先使用 `AuthContext.tenant_id`,并兼容 `X-Tenant-ID`(强制一致性校验)。
- 授权Authorization / RBAC在 Handler 层作为请求级拦截点调用 Service[authorization.rs](file:///home/shay/project/backend/iam-service/src/services/authorization.rs)),把“查库/规则”放在 Service 层,避免 Handler 直接拼 SQL。
更完整的“RBAC + ABAC 混合模型”落地建议见 [AUTHZ_DESIGN.md](file:///home/shay/project/backend/iam-service/AUTHZ_DESIGN.md)。
## 限流(生产建议)
- 登录/注册已在路由级挂载限流(见 [rate_limit.rs](file:///home/shay/project/backend/iam-service/src/middleware/rate_limit.rs))。
- 生产推荐在网关/边缘层做全局限流与 Bot 防护,服务内限流作为兜底。
- 可信代理模式:
- 配置 `TRUSTED_PROXY_CIDRS`,仅当对端连接 IP 命中这些网段时,才信任 `Forwarded` / `X-Forwarded-For` / `X-Real-IP` 提取真实客户端 IP 进行限流。
- 未命中可信代理时,将忽略这些 Header退回按对端连接 IP 限流,避免 Header 伪造绕过。
## 部署指南
### 本地/测试环境
- 使用 `.env` 配置连接串、端口、日志等
- 直接运行:`cargo run`
### 生产环境(建议)
- 构建:`cargo build --release`
- 以环境变量方式注入 `DATABASE_URL/JWT_SECRET/...`,避免把 `.env` 放入镜像或仓库
- 使用反向代理Nginx/Envoy处理 TLS、限流与审计日志视需求
## 测试
```bash
cargo test
```
当前仓库尚未包含单元测试/集成测试用例;建议在新增登录、鉴权与授权功能时补充覆盖(尤其是租户隔离与权限边界)。