Files
railwaysystem/docs/codebase-audit/06_security_and_permissions.md
T

6.5 KiB
Raw Blame History

权限与账号体系

1. 登录机制

当前使用若依标准的 Spring Security + JWT + Redis 登录链路:

  1. SysLoginController.login 接收 LoginBody,调用 SysLoginService.login。
  2. SysLoginService 通过 AuthenticationManager 完成用户名/密码认证,底层使用 UserDetailsServiceImpl 加载 sys_user。
  3. 密码使用 BCryptPasswordEncoder;密码重试与锁定由 SysPasswordService 配合 Redis 缓存处理。
  4. TokenService.createToken 生成 UUID,将完整 LoginUser 存入 Redis,并用 JJWT 生成 token。
  5. 客户端在 Authorization 请求头携带 token;JwtAuthenticationTokenFilter 解析后把认证对象放入 Spring SecurityContext。
  6. SecurityConfig 配置无状态会话,除白名单外的请求都需认证,并启用方法级权限。

代码依据:

  • RuoYi-Vue/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
  • RuoYi-Vue/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
  • RuoYi-Vue/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java
  • RuoYi-Vue/ruoyi-framework/src/main/java/com/ruoyi/framework/security/filter/JwtAuthenticationTokenFilter.java
  • RuoYi-Vue/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java

当前 SysLoginService.login 中验证码校验调用被注释掉;虽然 /captchaImage、配置项和缓存代码仍存在,实际登录服务当前不执行 validateCaptcha。这应在继续开发前作为当前事实确认,而不能只看登录页面是否显示验证码。

2. sys_user、sys_role、sys_menu

  • sys_user 是认证主体,关联部门、岗位与角色;SysUserMapper.xml、SysUserServiceImpl 和 SysUserController 保留完整管理能力。
  • sys_role 定义角色键、状态、菜单权限及 data_scope;通过 sys_user_role 关联用户,通过 sys_role_menu 关联菜单。
  • sys_menu 同时承载目录/菜单/按钮、前端路由组件和 perms 权限字符串。SysLoginController.getRouters 调用 SysMenuService.buildMenus 返回动态路由。
  • 初始化 SQL 只有若依内置 admin/common 角色及系统菜单;没有仓库内培训菜单 SQL。

3. 权限字符串如何定义和校验

后端 Controller 通过:

@PreAuthorize("@ss.hasPermi('system:teacher:list')")

调用 Spring Bean ss 的 PermissionService.hasPermi。当前登录用户的权限集合由 SysPermissionService.getMenuPermission 从角色/菜单关系加载,管理员获得通配权限。前端 v-hasPermi 指令按相同字符串决定按钮显示。

问题在于培训权限没有统一:

  • 后端 14 组使用 system:teacher:*、system:student:* 等 system:* 前缀。
  • 前端生成页面普遍使用 train:teacher:*、train:student:* 等 train:* 前缀。
  • 宿舍、教室、成绩三个后端 Controller 共用 system:info:*,权限粒度互相重叠。
  • 宿舍和成绩当前页面没有按钮权限指令。
  • 仓库没有培训 sys_menu.perms 数据可用于裁决哪一侧才是既定规范。

因此培训权限对超级管理员可能表面可用,对普通角色则很可能不能按预期工作。

4. 数据权限

若依数据权限框架存在:

  • @DataScope 注解。
  • DataScopeAspect 根据角色的 data_scope 拼接部门/本人范围 SQL。
  • SysRole 保存数据范围配置。

当前 @DataScope 只在若依系统域的 SysUserServiceImpl、SysRoleServiceImpl、SysDeptServiceImpl 等位置使用;ruoyi-train 未发现 @DataScope,培训 Mapper SQL也没有部门、教师或班级范围条件。

所以“数据权限能力可复用”成立,“培训数据已经受数据权限保护”不成立。

5. 教师、学员与账号关联

  • TrainTeacher 没有 userId/用户名字段,Mapper 不查询 sys_user。
  • TrainStudent 同样没有 userId/用户名字段。
  • train_class_plan 只有 t_id,表示计划中的授课教师工号;没有将当前登录 sys_user 映射到 t_id 的关系。
  • 培训 Service/Mapper 没有基于当前登录人过滤计划、学员、成绩或签到。

结论:当前没有“教师只能查看自己所带班级”的实现,也没有学员只能查看本人数据的实现。

6. 操作日志

若依 @Log + LogAspect + 异步日志组件保留。培训 Controller 对以下动作加了日志:

  • Excel 导出:BusinessType.EXPORT
  • 新增:INSERT
  • 修改:UPDATE
  • 删除:DELETE

可记录的主要内容包括业务标题、业务类型、HTTP 方法、请求 URI、操作者、部门、IP、请求参数、返回结果、成功/失败状态、错误消息和耗时,并写入 sys_oper_log。

培训列表/详情读取通常没有 @Log。现有日志是接口操作记录,不是领域审计轨迹;没有修改前快照、字段级差异、报到/设备下发状态机流水或外部请求/回执详情。

代码依据:LogAspect.java、SysOperLog.java、AsyncFactory.java 及 14 个培训 Controller。

7. 导入导出权限

  • 若依系统用户模块支持 system:user:import、system:user:export,并提供导入模板。
  • ExcelUtil 是通用能力,可被培训模块复用。
  • 14 个培训 Controller 都有后端 Excel 导出接口与 *:export 权限;多数前端页面也有导出按钮。
  • 培训模块没有任何导入接口、导入模板接口或 *:import 权限。成绩的 source_type=2 Excel批量导入 只是字段枚举含义,不代表导入功能存在。

8. 是否需要重造权限系统

不需要。现有若依登录、用户、角色、菜单、按钮权限、数据权限与日志框架应直接复用。

继续开发需要在现有体系内补齐培训权限:统一权限命名;向 sys_menu 增加培训目录、页面和按钮权限;建立 sys_user 与教师/学员业务身份关系;明确教师、学员和管理员的数据范围规则;在培训查询入口应用数据权限或业务范围过滤。以上是后续设计方向,本次未修改任何系统表或代码。

9. 需要进一步确认的安全运行配置

  • JWT secret、数据库账号口令和 Druid 控制台口令目前以明文配置存在;本报告不复述具体值。
  • 登录页当前有未提交的默认口令改动。
  • 验证码校验在登录服务中被注释。
  • SecurityConfig 对上传资源路径存在匿名 GET 配置,需与实际公开文件范围共同评审。

这些事实会影响上线基线,但本次审计没有自动修复。