infra-parent 是一套基于 Spring Boot 4 的多租户基础服务,核心提供 UPM(User Permission Management)用户权限中心。它既可以作为统一认证与权限中心独立部署,也可以通过 Maven 模块直接集成到业务系统。
项目当前已经覆盖租户、应用、组织、RBAC、数据权限、SSO 和第三方账号登录等基础能力。1.2.0开发版已接入工作流定义设计和个人审批中心;文件、通知仍是预留模块,具体业务流程后续按需接入。
租户
├── 应用 A
│ ├── Web 端
│ │ └── 目录 / 菜单 / 按钮
│ └── App 端
│ └── 目录 / 菜单 / 按钮
└── 应用 B
└── Web 端
└── 目录 / 菜单 / 按钮
用户 ──分配──> 角色 ──授权──> 不同应用、终端下的菜单按钮
| 类型 | 技术 |
|---|---|
| 构建 JDK | JDK 25(产物目标版本为 Java 21) |
| Web 框架 | Spring Boot 4.1.2 |
| ORM | MyBatis Plus 3.5.18 |
| 数据库 | MySQL 5.7 / 8.x(同时提供 PostgreSQL SQL 脚本) |
| 缓存 | Redis、Redisson、JetCache |
| 认证授权 | Sa-Token 1.45.0 |
| API 文档 | Knife4j-next |
| 工具库 | Hutool 7 |
| 动态线程池 | Dynamic-TP |
| 任务调度 | PowerJob |
infra-parent
├── common
│ ├── common-core # 基础工具、常量和通用模型
│ ├── common-api # 跨模块公共 API 模型
│ ├── common-auth # Sa-Token 认证授权封装
│ ├── common-redisson # Redisson、分布式锁和限流
│ └── common-web # Web、MyBatis Plus、数据权限和 API 文档
├── upm
│ ├── upm-api # UPM 实体、请求响应对象和服务契约
│ ├── upm-core # UPM 业务、HTTP 接口、SSO Server 和内置前端
│ └── upm-start # UPM 独立部署入口
├── file # 文件服务预留模块(规划中)
├── shortlink # 短链 API 契约与实现
├── notice # 通知服务预留模块(规划中)
├── flow # Warm-Flow 1.8.9 工作流底座、流程定义与个人审批中心
├── ai # AI 能力预留模块
├── infra-start # 基础能力统一部署入口
├── doc # 架构与接入文档
├── sql # 全量初始化与增量升级脚本
└── bin # 本地安装和发布脚本
infra-start 用于将多个基础能力组合成一个大单体服务;upm-start 只启动 UPM,适合独立部署或后续微服务拆分。
前端项目独立维护在 infra-parent-web,生产构建产物会放入 upm-core,因此启动后端即可访问管理端页面。
仓库同时维护 PostgreSQL 全量及增量脚本;使用 PostgreSQL 运行服务时,需要在启动模块中补充 PostgreSQL JDBC 驱动并调整数据源配置。
MySQL:
mysql -u root -p infra < sql/full/mysql.sql
新数据库只执行 sql/full/ 中对应的全量脚本;已有数据库按时间顺序执行 sql/migration/ 中尚未应用的增量脚本,不要重复执行全量脚本或已经执行过的迁移。
完整说明见 SQL 执行说明。
统一启动时修改:
infra-start/src/main/resources/application-dev.properties
仅启动 UPM 时修改:
upm/upm-start/src/main/resources/application-dev.properties
至少需要配置数据库和 Redis。真实密码、第三方平台密钥及 API Key 应通过环境变量或部署平台的密钥管理功能注入,不要提交到 Git。
启用 SSO 前还需要生成用于加密客户端密钥的主密钥:
openssl rand -base64 32
export UPM_SSO_SECRET_KEY="替换为上一步生成的固定值"
该值必须由部署平台长期安全保存。应用密钥加密入库后不能随意重新生成,否则已有密文将无法解密。
mvn clean install
也可以使用安装脚本:
cd bin
./install.sh
统一启动全部基础模块:
cd infra-start
mvn spring-boot:run -Dspring-boot.run.profiles=dev
只启动 UPM:
cd upm/upm-start
mvn spring-boot:run -Dspring-boot.run.profiles=dev
启动后访问:
默认账号:
| 类型 | 账号 | 密码 |
|---|---|---|
| 平台管理员 | platform@yilers.com |
yilers@123 |
| 默认租户管理员 | admin@yilers.com |
yilers@123 |
首次登录后建议立即修改默认密码。
租户 1 是平台模板租户,内置基础管理应用。平台管理员可以维护模板应用、菜单和按钮,并在租户管理页面预览、同步其他租户的权限差异。
创建新租户时会自动完成:
目标租户可以继续创建自己的应用和菜单。租户自建菜单不会被平台同步覆盖。
详细规则见 租户应用菜单同步。
独立部署模式下,UPM 作为统一认证中心。业务系统在 UPM 中配置为租户应用,并使用以下客户端标识:
{tenantCode}:{applicationCode}
例如:
yilers.com:oa
应用可以配置名称、编码、Logo、首页地址、回调地址白名单、注销推送地址、SSO 开关和客户端密钥。
登录流程:
/sso/authorize 页面。/sso/pushS 校验 ticket 并获取租户、应用、用户、角色、菜单、按钮及数据权限上下文。UPM 与业务系统不需要共享 Redis,客户端密钥只允许保存在业务后端。UPM token、业务 token 和一次性 ticket 的职责彼此独立。
完整协议、安全边界和接口示例见 SSO 接入文档。
新业务应用的配置步骤、后端及前端代码示例、联调排查见 SSO Client 接入指南。
第三方认证用于解决“用户如何登录 UPM”,与用于进入业务应用的 SSO 是两套不同流程。
当前已实现:
当前不会根据钉钉身份自动创建 UPM 用户,也不会在登录回调中同步钉钉部门和组织架构。用户必须先登录 UPM 并完成账号绑定,后续才能使用钉钉登录。
推荐授权回调地址:
https://upm.example.com/third-auth-callback.html
完整配置、绑定及登录流程见 第三方认证文档。
运行 upm-start,业务系统通过 HTTP 和 SSO 使用 UPM。业务数据库与 UPM 数据库可以完全独立,适合统一认证中心和多业务系统场景。
业务启动器直接依赖 upm-core,在自己的数据库中部署 UPM 表,使用本地 Service、登录和权限能力:
<dependency>
<groupId>io.github.yilers</groupId>
<artifactId>upm-core</artifactId>
<version>1.1.1</version>
</dependency>
只需要实体、请求响应对象或服务契约时,可以依赖 upm-api。建议业务模块同样采用 api + core + start 分层。
上面的依赖版本使用上一正式发布版,不是当前源码的 1.2.0 开发版本;1.2.0 完成并发布后再更新该示例。源码构建版本由父 POM 的 revision 决定,无需在每条 Maven 命令中重复指定。
模块集成与独立 SSO 是两种不同部署方式:业务系统已经集成本地 upm-core 和 UPM 数据表时,通常直接使用本地登录,不再连接另一套独立 UPM。
部门管理支持设置主管和副主管,任职关系保存在 upm_dept_leader;用户列表会展示当前任职标签。主管身份是组织信息,不会自动授予角色、菜单或数据权限。已有数据库升级时执行对应的 20261014_dept_leader 增量脚本,并为其他租户同步新按钮后按需授权。
角色默认数据范围支持:
用户数据权限可以针对具体业务接口覆盖角色默认范围。业务接口使用 @DataPermissionResource 标记可配置接口,并以 Spring 实际匹配的路由模板保存资源路径,因此 /user/{id} 不会退化成具体 ID 的动态地址。Mapper 使用 @DataPermission 声明主表、部门字段和创建人字段。
示例:
@InterceptorIgnore(tenantLine = "true", dataPermission = "false")
@DataPermission(tableName = "upm_log", deptField = "dept_id", userField = "operator")
Page<LogInfoResponse> findByPage(@Param("page") Page<?> page,
@Param("request") BasePageRequest<Log> request);
需要列权限处理的表可在配置中声明:
permission.column.table=upm_log,upm_user
# 完整构建
mvn clean install
# 跳过测试构建
mvn clean install -DskipTests
# 打包
mvn clean package -DskipTests
# 显式运行测试
mvn test -DskipTests=false
# 查看依赖树
mvn dependency:tree

