Files
springboot-template/DETAILS.md
shenjianZ 40c85c3c1f feat: 实现完整的 RBAC 权限管理系统与基础设施增强
在初始认证基础上,新增完整的 RBAC 权限模型(角色、权限、菜单三级管理),
  集成审计日志、接口限流、登录失败锁定、Refresh Token 机制、Redis 分布式缓存与锁、
  RocketMQ 消息队列,并引入 Flyway 数据库版本管理,同时补充项目文档与使用示例
2026-04-10 10:58:22 +08:00

35 KiB
Raw Permalink Blame History

📋 项目概览

这是一个企业级 Spring Boot 3.x 模板项目,提供了完整的用户认证与权限管理系统。

核心功能

┌─────────────────────────────────────────────────────────────┐ │ 核心功能模块 │ ├─────────────────────────────────────────────────────────────┤ │ 1. 用户认证 JWT + Refresh Token 双Token机制 │ │ 2. 权限管理 RBAC角色-权限)模型 │ │ 3. 账户安全 登录失败锁定、密码重置、限流 │ │ 4. 审计日志 记录所有敏感操作 │ │ 5. 缓存支持 Redis 缓存、分布式锁 │ │ 6. 消息队列 RocketMQ 异步处理 │ └─────────────────────────────────────────────────────────────┘

技术栈

Searched for 1 pattern, read 1 file (ctrl+o to expand)

● 现在让我为你详细剖析整个项目:


一、项目技术栈

┌─────────────────┬────────┬────────────────┐ │ 技术 │ 版本 │ 用途 │ ├─────────────────┼────────┼────────────────┤ │ Spring Boot │ 3.5.6 │ 基础框架 │ ├─────────────────┼────────┼────────────────┤ │ Spring Security │ 6.x │ 认证授权 │ ├─────────────────┼────────┼────────────────┤ │ Spring Data JPA │ - │ ORM 数据访问 │ ├─────────────────┼────────┼────────────────┤ │ MySQL │ - │ 关系数据库 │ ├─────────────────┼────────┼────────────────┤ │ Redis │ - │ 缓存/分布式锁 │ ├─────────────────┼────────┼────────────────┤ │ RocketMQ │ 2.3.1 │ 消息队列 │ ├─────────────────┼────────┼────────────────┤ │ JJWT │ 0.11.5 │ JWT Token │ ├─────────────────┼────────┼────────────────┤ │ Flyway │ - │ 数据库版本管理 │ ├─────────────────┼────────┼────────────────┤ │ Lombok │ - │ 简化代码 │ └─────────────────┴────────┴────────────────┘


二、项目目录结构

● Bash(tree -L 4 -I 'target|.git' D:\tmp\springboot-template\src\main\java\com\aisi\template 2>/dev/null || find D:\tmp\springboot-template\src\main\java\com\aisi\temp…) ⎿  find: D:tmpspringboot-templatesrcmainjavacomaisitemplate: No such file or directory sed: -e expression #1, char 7: unterminated `s' command

Searched for 1 pattern (ctrl+o to expand)

● 项目分层架构 │ ├── 📁 annotation/ # 自定义注解AOP切点 │ ├── @AuditLog # 审计日志注解 │ ├── @RateLimit # 限流注解 │ └── @StrongPassword # 强密码校验注解 │ ├── 📁 aspect/ # AOP切面 │ ├── AuditLogAspect # 审计日志切面 │ └── RateLimitAspect # 限流切面 │ ├── 📁 config/ # 配置类 │ ├── SecurityConfig # Spring Security 安全配置 │ ├── RedisConfig # Redis 配置 │ ├── JpaConfig # JPA 审计配置 │ ├── WebConfig # Web MVC 配置 │ ├── JacksonConfig # JSON 序列化配置 │ └── OpenApiConfig # Swagger 文档配置 │ ├── 📁 constants/ # 常量定义 │ ├── AppConstants # 应用常量 │ └── SecurityConstants # 安全常量 │ ├── 📁 controller/ # 控制层API接口 │ ├── UserController # 用户接口 │ ├── RoleController # 角色接口 │ ├── MenuController # 菜单接口 │ └── PermissionController # 权限接口 │ ├── 📁 domain/ # 领域模型 │ ├── entity/ # 实体类(数据库表) │ ├── dto/ # 数据传输对象(请求参数) │ ├── vo/ # 视图对象(响应数据) │ └── enums/ # 枚举类 │ ├── 📁 service/ # 服务层(业务逻辑) │ └── impl/ # 服务实现 │ ├── 📁 repository/ # 数据访问层DAO │ ├── 📁 filter/ # 过滤器 │ └── JwtAuthenticationFilter # JWT 认证过滤器 │ ├── 📁 handler/ # 处理器 │ └── GlobalExceptionHandler # 全局异常处理 │ ├── 📁 interceptor/ # 拦截器 │ └── LoggingInterceptor # 日志拦截器 │ ├── 📁 mq/ # 消息队列 │ ├── producer/ # 消息生产者 │ ├── consumer/ # 消息消费者 │ └── message/ # 消息定义 │ ├── 📁 utils/ # 工具类 │ ├── JwtUtil # JWT 工具 │ ├── SecurityUtils # 安全工具 │ ├── RedisCache # Redis 缓存 │ └── RedisLock # 分布式锁 │ ├── 📁 examples/ # 使用示例 │ ├── RedisUsageExample # Redis 使用示例 │ └── TransactionExample # 事务使用示例 │ └── 📁 exception/ # 异常类 ├── BusinessException # 业务异常 └── RateLimitExceededException # 限流异常


三、核心架构设计

3.1 认证架构

┌─────────────────────────────────────────────────────────────────┐ │ 认证流程 │ └─────────────────────────────────────────────────────────────────┘

客户端 Spring Boot JWT Token │ │ │ │ 1. POST /api/v1/user/login │ │ │ {username, password} │ │ │ ────────────────────────────>│ │ │ │ │ │ │ 2. 验证用户名密码 │ │ │ 3. 检查账户锁定状态 │ │ │ 4. 生成 Access Token(1h) │ │ │ 5. 生成 Refresh Token(7d) │ │ │ 6. 存储 Refresh Token │ │ │ │ │ 7. 返回 Token │ │ │ {accessToken, │ │ │ refreshToken} │ │ │ <────────────────────────────│ │ │ │ │ │ 8. 后续请求携带 Token │ │ │ Authorization: Bearer │ │ │ {accessToken} │ │ │ ────────────────────────────>│ │ │ │ │ │ │ 9. JwtAuthenticationFilter │ │ │ 解析 Token │ │ │ 验证签名 │ │ │ 检查黑名单 │ │ │ 设置认证上下文 │ │ │ │ │ 10. 返回业务数据 │ │ │ <────────────────────────────│ │

3.2 权限模型RBAC

┌─────────────────────────────────────────────────────────────────┐ │ RBAC 权限模型 │ └─────────────────────────────────────────────────────────────────┘

 用户(User) ──多对多── 角色(Role) ──多对多── 权限(Permission)
     │                  │                    │
     │                  │                    │
 having            having               having
accounts           roles               permissions

示例: 用户 alice ──拥有──> [ROLE_USER, ROLE_ADMIN] │ └── ROLE_ADMIN ──拥有──> [user:read, user:write, role:read, menu:read]

权限计算: alice 的权限 = ROLE_USER的权限 ROLE_ADMIN的权限

使用 @PreAuthorize 注解控制访问: @PreAuthorize("hasAuthority('user:write')") public void updateUser() { ... }

3.3 安全防护机制

┌─────────────────────────────────────────────────────────────────┐ │ 安全防护体系 │ └─────────────────────────────────────────────────────────────────┘

防护类型 实现方式 阈值 ───────────────────────────────────────────────────────────────── 登录失败锁定 Redis计数器 + 时间窗口 5次/30分钟 密码重置限流 Redis计数器 + 冷却时间 1次/60秒 API接口限流 Redis + @RateLimit切面 可配置 密码强度校验 @StrongPassword注解 大小写+数字+特殊字符 Token黑名单 Redis + JTI 登出时加入 Token轮换 Refresh Token机制 刷新后旧Token失效 密码重置 邮箱验证码 6位/10分钟有效


四、数据库设计

Searched for 1 pattern, read 2 files (ctrl+o to expand)

● 数据库表结构

┌─────────────────────────────────────────────────────────────────┐ │ 数据库表关系图 │ └─────────────────────────────────────────────────────────────────┘

核心表关系:

users (用户表) │ ├── 1:N ──> refresh_tokens (刷新令牌表) │ ├── N:M ──> sys_role (角色表) ── N:M ──> sys_permission (权限表) │ │ │ │ └── N:M ──> sys_menu (菜单表) │ │ │ └── 1:N ──> password_reset_codes (密码重置码表)

辅助表: ├── sys_audit_log (审计日志表) └── sys_user_role (用户-角色关联表) sys_role_permission (角色-权限关联表) sys_role_menu (角色-菜单关联表)

┌────────────────┬──────────┬─────────────────────────────────────────────────────────────────────┐ │ 表名 │ 用途 │ 关键字段 │ ├────────────────┼──────────┼─────────────────────────────────────────────────────────────────────┤ │ users │ 用户信息 │ username, password, email, status, failed_login_count, locked_until │ ├────────────────┼──────────┼─────────────────────────────────────────────────────────────────────┤ │ sys_role │ 角色定义 │ role_code(ROLE_ADMIN等), role_name, status │ ├────────────────┼──────────┼─────────────────────────────────────────────────────────────────────┤ │ sys_permission │ 权限定义 │ permission_code(user:read等), resource, action │ ├────────────────┼──────────┼─────────────────────────────────────────────────────────────────────┤ │ sys_menu │ 菜单定义 │ menu_name, menu_type(目录/页面/按钮), parent_id │ ├────────────────┼──────────┼─────────────────────────────────────────────────────────────────────┤ │ refresh_tokens │ 刷新令牌 │ token_hash(SHA-256), expires_at, revoked │ ├────────────────┼──────────┼─────────────────────────────────────────────────────────────────────┤ │ sys_audit_log │ 审计日志 │ user_id, action(LOGIN/CREATE等), resource, status │ └────────────────┴──────────┴─────────────────────────────────────────────────────────────────────┘


五、核心模块详解

5.1 认证模块

核心类关系: SecurityConfig (配置入口) │ ├── CustomUserDetailsService (加载用户) │ └── UserRepository (查询用户) │ ├── JwtAuthenticationFilter (JWT过滤器) │ ├── JwtUtil (Token生成/解析) │ └── TokenService (Token管理) │ └── RefreshTokenRepository │ └── PasswordEncoder (BCrypt加密)

认证流程详解:

Read 1 file (ctrl+o to expand)

● JWT认证过滤器详解

Read 1 file (ctrl+o to expand)

● 认证流程图

┌─────────────────────────────────────────────────────────────────────────┐ │ 完整认证流程 │ └─────────────────────────────────────────────────────────────────────────┘

  1. 用户登录 │ ├─> UserController.login() │ │ │ ├─> UserService.login() │ │ │ │ │ ├─> 1. 校验用户名密码 │ │ ├─> 2. 检查账户锁定状态 │ │ ├─> 3. 检查账户启用状态 │ │ ├─> 4. 记录登录失败(成功则清除) │ │ ├─> 5. 生成 Access Token (1小时) │ │ ├─> 6. 生成 Refresh Token (7天) │ │ ├─> 7. 存储 Refresh Token 到数据库 │ │ ├─> 8. 发送登录消息到 MQ │ │ └─> 9. 返回 LoginResponseVo │ │ │ └─> 返回 { accessToken, refreshToken, expiresIn, userInfo }

  2. 后续请求 │ ├─> JwtAuthenticationFilter.doFilterInternal() │ │ │ ├─> 1. 提取 Token (Authorization: Bearer {token}) │ ├─> 2. 验证 Token 签名 │ ├─> 3. 检查黑名单 (登出时加入) │ ├─> 4. 检查过期时间 │ ├─> 5. 加载用户详情 │ └─> 6. 设置认证到 SecurityContext │ └─> 继续处理请求

  3. Token 刷新 │ ├─> UserController.refreshToken() │ │ │ └─> TokenService.refreshToken() │ │ │ ├─> 1. 验证 Refresh Token │ ├─> 2. 撤销旧 Refresh Token │ ├─> 3. 生成新的 Access Token │ ├─> 4. 生成新的 Refresh Token │ └─> 5. 返回新 Token

  4. 用户登出 │ ├─> UserController.logout() │ │ │ └─> TokenService.addTokenToBlacklist() │ │ │ ├─> 1. 提取 Token 的 JTI │ ├─> 2. 计算剩余过期时间 │ ├─> 3. 存入 Redis 黑名单 │ └─> 4. 撤销所有 Refresh Token

5.2 权限模块详解

Read 1 file (ctrl+o to expand)

● 权限加载流程

┌─────────────────────────────────────────────────────────────────────────┐ │ 权限加载与验证流程 │ └─────────────────────────────────────────────────────────────────────────┘

  1. 用户登录时加载权限 │ ├─> CustomUserDetailsService.loadUserByUsername(username) │ │ │ ├─> 查询用户: User + Roles (JOIN FETCH) │ │ │ ├─> 遍历用户的每个角色 │ │ │ │ │ └─> 角色 ROLE_ADMIN │ │ │ │ │ ├─> 添加角色权限: "ROLE_ADMIN" │ │ │ │ │ └─> 添加角色下的具体权限 │ │ ├── "user:create" │ │ ├── "user:read" │ │ ├── "user:update" │ │ ├── "role:read" │ │ └── ... │ │ │ └─> 合并所有角色的权限 → Set

  2. 接口权限验证 │ ├─> @PreAuthorize("hasAuthority('user:create')") │ │ │ └─> Spring Security 检查当前用户的权限列表 │ │ │ └─> 包含 "user:create" → 允许访问 │ 不包含 → 拒绝访问

  3. 权限类型说明 │ ├── 角色权限 (ROLE_XXX) │ ├── 用于粗粒度控制:判断用户角色 │ └── 使用方式: @PreAuthorize("hasRole('ADMIN')") │ 等价于: hasAuthority('ROLE_ADMIN') │ └── 具体权限 (XXX:YYY) ├── 用于细粒度控制:具体操作 └── 使用方式: @PreAuthorize("hasAuthority('user:create')")

5.3 安全防护模块

Read 1 file (ctrl+o to expand)

● 安全防护机制详解

┌─────────────────────────────────────────────────────────────────────────┐ │ 安全防护机制 │ └─────────────────────────────────────────────────────────────────────────┘

  1. 登录失败锁定机制 │ ├─> 触发条件:连续登录失败 5 次(可配置) │ ├─> 锁定时长30 分钟(可配置) │ ├─> 实现方式: │ ├── users 表存储失败次数和锁定时间 │ ├── failed_login_count失败次数 │ └── locked_until锁定到期时间 │ └─> 自动解锁:锁定时间到期后自动解锁

  2. 限流机制 (@RateLimit) │ ├─> 支持的限流类型: │ ├── IP按 IP 地址限流 │ ├── USER按用户 ID 限流 │ └── GLOBAL全局限流 │ ├─> 使用方式: │ @RateLimit(permitted = 10, seconds = 60, limitType = LimitType.USER) │ public void sensitiveOperation() { ... } │ └─> 实现原理: ├── Redis 存储计数器 ├── 格式rate_limit:user:{userId} ├── 过期时间:时间窗口 └── 超过限制:抛出 RateLimitExceededException

  3. 密码重置机制 │ ├─> 验证码规则: │ ├── 6 位随机数字 │ ├── 10 分钟有效期 │ ├── 最多尝试 5 次 │ └── 60 秒请求冷却时间 │ ├─> 防用户名枚举: │ └── 无论邮箱是否存在,都返回相同消息 │ └─> 验证码存储: ├── 哈希存储SHA-256 └── 数据库 + 状态管理

  4. Token 黑名单机制 │ ├─> 触发场景: │ ├── 用户主动登出 │ ├── 管理员强制下线 │ └── 修改密码后 │ ├─> 存储方式Redis │ └─> 键格式token:blacklist:{jti} │ └── 过期时间Token 剩余有效期

5.4 审计日志模块

Read 1 file (ctrl+o to expand)

● 审计日志使用示例

// 在方法上添加 @AuditLog 注解 @AuditLog( action = "CREATE", resource = "user", description = "创建用户 {0}" ) public void createUser(String username) { // 业务逻辑 }

// AOP 切面会自动记录: // - 操作用户(从 SecurityContext 获取) // - 操作类型CREATE // - 资源类型user // - 操作描述:"创建用户 alice" // - 请求信息IP、User-Agent // - 操作结果:成功/失败

5.5 Redis 缓存模块

Read 1 file (ctrl+o to expand)

● Redis 缓存使用场景

┌─────────────────────────────────────────────────────────────────────────┐ │ Redis 使用场景总结 │ └─────────────────────────────────────────────────────────────────────────┘

  1. Token 黑名单 ├── 键格式token:blacklist:{jti} ├── 值1固定值只判断键是否存在 └── 过期时间Token 剩余有效期

  2. Refresh Token 存储 ├── 键格式refresh_token:{tokenHash} ├── 值用户ID └── 过期时间7 天

  3. 限流计数器 ├── 键格式rate_limit:{type}:{identifier} │ ├── type: ip / user / global │ └── identifier: IP地址 / 用户ID ├── 值:当前请求次数 └── 过期时间:时间窗口

  4. 登录失败计数 ├── 键格式login_attempts:{username} ├── 值:失败次数 └── 过期时间锁定时长30分钟

  5. 分布式锁 ├── 键格式lock:{resource}:{id} ├── 值唯一标识UUID ├── 过期时间:锁超时时间(防止死锁) └── 实现方式SET NX EX + Lua 脚本

  6. 用户会话缓存 ├── 键格式session:user:{userId} ├── 值会话信息登录IP、时间等 └── 过期时间24 小时

  7. 密码重置验证码 ├── 存储:数据库 password_reset_codes 表 └── 限制Redis + 冷却时间

5.6 消息队列模块

Read 3 files (ctrl+o to expand)

● RocketMQ 消息队列架构

┌─────────────────────────────────────────────────────────────────────────┐ │ RocketMQ 消息流程 │ └─────────────────────────────────────────────────────────────────────────┘

用户登录 │ ├─> UserService.login() │ │ │ ├─> 1. 验证用户 │ ├─> 2. 生成 Token │ ├─> 3. 发送登录消息到 MQ │ │ │ │ │ └─> UserMessageProducer.sendLoginMessage() │ │ │ │ │ └─> rocketMQTemplate.asyncSend(user-topic, message) │ │ │ └─> 4. 返回响应(不等待 MQ 处理) │ │ └─> RocketMQ: user-topic │ └─> UserMessageConsumer.onMessage() │ ├─> 1. 收到消息 ├─> 2. 根据 messageType 路由 │ │ │ ├── REGISTER → handleRegisterMessage() │ │ └─> 发送欢迎邮件、初始化数据 │ │ │ ├── LOGIN → handleLoginMessage() │ │ └─> 记录登录日志、更新最后登录时间 │ │ │ ├── LOGOUT → handleLogoutMessage() │ │ └─> 清理缓存、登出其他设备 │ │ │ ├── UPDATE → handleUpdateMessage() │ │ └─> 同步数据到数据仓库、清除缓存 │ │ │ └── DELETE → handleDeleteMessage() │ └─> 清理关联数据、归档 │ └─> 3. 处理完成,确认消费


六、配置文件解析

Searched for 1 pattern, read 2 files (ctrl+o to expand)

● 配置文件结构总结

┌─────────────────────────────────────────────────────────────────────────┐ │ 配置文件结构 │ └─────────────────────────────────────────────────────────────────────────┘

application.yaml (主配置) ├── spring.profiles.active: dev (激活环境) ├── server.port: 8080 └── 支持环境变量覆盖 (.env 文件)

application-dev.yaml (开发环境) ├── 数据库配置 (MySQL) │ ├── url: jdbc:mysql://localhost:3306/template │ ├── username: root │ └── password: root ├── JPA 配置 │ ├── ddl-auto: validate (不自动建表,由 Flyway 管理) │ └── show-sql: false ├── Flyway (数据库版本管理) │ ├── enabled: true │ └── locations: classpath:db/migration ├── Redis 配置 │ ├── host: localhost:6379 │ └── database: 0 ├── 邮件配置 (SMTP) │ ├── host: smtp.163.com │ └── port: 465 ├── JWT 配置 │ ├── secret: 密钥HS512 需要 64 字符) │ ├── access-token-expiration: 3600 秒 (1 小时) │ └── refresh-token-expiration: 604800 秒 (7 天) ├── 业务配置 │ ├── 登录失败锁定: 5 次 / 30 分钟 │ └── 密码重置: 6 位验证码 / 10 分钟有效 └── RocketMQ 配置 └── name-server: localhost:9876


七、请求处理完整流程

┌─────────────────────────────────────────────────────────────────────────┐ │ 完整请求处理流程 │ └─────────────────────────────────────────────────────────────────────────┘

  1. 客户端发起请求 │ ├─> GET /api/v1/user/info │ Headers: │ - Authorization: Bearer {accessToken} │ - Content-Type: application/json │ │
  2. 进入 Spring MVC 处理链 │ ├─> LoggingInterceptor (拦截器) │ ├── 记录请求开始时间 │ ├── 生成请求 ID (8 位 UUID) │ ├── 获取当前用户信息 │ └── 记录请求开始日志 │ │
  3. 进入 Filter 链 │ ├─> JwtAuthenticationFilter (JWT 过滤器) │ ├── 提取 Token: Bearer {token} │ ├── 验证 Token 签名 (HS512) │ ├── 检查黑名单 (Redis: token:blacklist:{jti}) │ ├── 检查过期时间 │ ├── 加载用户详情 │ └── 设置认证到 SecurityContext │ │
  4. 权限验证 │ ├─> @PreAuthorize("hasAuthority('user:read')") │ └── 检查用户权限列表是否包含 "user:read" │ │
  5. AOP 切面处理 │ ├─> AuditLogAspect (审计日志切面) │ ├── 检查 @AuditLog 注解 │ ├── 提取请求信息 │ ├── 提取当前用户信息 │ └── 准备记录审计日志(异步执行) │ │
  6. 执行 Controller │ ├─> UserController.getUserInfo() │ ├── 从 SecurityContext 获取用户 │ └── 返回用户信息 (UserVo) │ │
  7. 响应处理 │ ├─> 全局异常处理 │ └── GlobalExceptionHandler │ ├── 捕获业务异常 │ ├── 捕获参数校验异常 │ └── 捕获系统异常 │ │
  8. 后置处理 │ ├─> LoggingInterceptor.afterCompletion() │ ├── 计算请求耗时 │ └── 记录请求完成日志 │ └─> 返回响应 └─> RestBean ├── code: 200 ├── message: "操作成功" └── data: UserVo

八、总结与建议

项目优势

  1. 架构清晰:分层明确,职责单一
  2. 安全完善JWT + RBAC + 多重防护
  3. 扩展性强:模块化设计,易于扩展
  4. 文档完整:全中文注释,便于维护
  5. 异步解耦RocketMQ 消息队列

适用场景

  • 企业内部管理系统
  • SaaS 多租户平台
  • 需要 RBAC 权限的系统
  • 需要审计日志的系统
  • 需要高安全性的系统

扩展建议

  1. 数据权限:在 RBAC 基础上增加数据权限控制
  2. 多租户:添加租户隔离机制
  3. OAuth2支持第三方登录微信、GitHub等
  4. 监控告警:集成 Prometheus + Grafana
  5. 日志收集:集成 ELKElasticsearch + Logstash + Kibana