Files
cattleTransportation/pc-cattle-transportation/PERMISSION_MANAGEMENT_EXPLANATION.md
2025-10-23 17:28:06 +08:00

153 lines
4.7 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.

# 权限管理机制说明
## 问题描述
用户反映:修改"12.27新增姓名"这个用户的操作权限时,超级管理员的权限也会被修改。
## 根本原因
当前系统使用的是**基于角色的权限管理RBAC - Role-Based Access Control**而不是基于用户的权限管理UBAC - User-Based Access Control
### 权限架构分析
1. **数据库表结构**
- `sys_role_menu` 表:存储角色-菜单权限关系
- `sys_user` 表:存储用户信息,包含 `roleId` 字段
- **没有** `sys_user_menu` 表:不存在用户-菜单权限关系
2. **权限分配机制**
- 权限分配基于 `roleId`角色ID
- 所有使用相同 `roleId` 的用户共享相同的权限
- 修改权限时影响整个角色,不是单个用户
3. **权限获取流程**
```java
// LoginServiceImpl.java 第124行
List<String> permissions = queryUserPermissions(user.getRoleId());
```
- 用户登录时,根据用户的 `roleId` 获取权限
- 不是根据用户的 `userId` 获取权限
## 具体案例分析
### 用户信息对比
| 用户 | 用户ID | 角色ID | 权限来源 |
|------|--------|--------|----------|
| 12.27新增姓名 | 3 | 1 | roleId=1 的权限 |
| 超级管理员 | 11 | 1 | roleId=1 的权限 |
### 权限修改影响
当修改"12.27新增姓名"的权限时:
1. 前端发送请求:`{ roleId: 1, menuIds: [...] }`
2. 后端更新 `sys_role_menu` 表中 `roleId=1` 的记录
3. 所有使用 `roleId=1` 的用户权限都被更新
4. 包括"超级管理员"在内的所有 `roleId=1` 用户都受到影响
## 解决方案
### 方案1修改为基于用户的权限管理推荐但复杂
需要:
1. 创建 `sys_user_menu` 表
2. 修改后端API支持用户级别权限
3. 修改权限查询逻辑
4. 修改前端界面
### 方案2明确显示角色权限管理已实施
已实施的改进:
1. **界面标识**:添加"基于角色权限"标签
2. **角色ID显示**在用户列表中显示角色ID
3. **警告提示**:明确说明影响范围
4. **确认对话框**:保存前确认影响范围
5. **成功提示**:明确说明影响范围
## 修改内容
### 前端界面改进
1. **用户列表**
- 添加"基于角色权限"标签
- 显示角色ID列
2. **权限分配区域**
- 标题改为"角色权限分配"
- 显示当前角色ID
- 添加详细的警告提示
3. **保存确认**
- 添加确认对话框
- 明确说明影响范围
- 成功提示包含影响范围
### 警告信息内容
```
重要提示 - 基于角色的权限管理
• 当前系统使用基于角色的权限管理RBAC
• 修改权限会影响所有使用相同角色ID的用户
• 当前用户角色ID: 1
• 所有角色ID为 1 的用户都会受到影响
• 勾选操作权限后,该角色可以执行相应的按钮操作(新增、编辑、删除等)
```
## 建议
1. **短期解决方案**:使用当前的界面改进,让用户明确知道这是角色权限管理
2. **长期解决方案**:考虑实施基于用户的权限管理,但这需要较大的系统改造
3. **用户培训**:向用户说明权限管理机制,避免误解
## 技术细节
### 权限查询流程
```java
// 用户登录时获取权限
List<String> permissions = queryUserPermissions(user.getRoleId());
// 权限查询方法
private List<String> queryUserPermissions(Integer roleId) {
// 查询角色关联的菜单权限
List<SysMenu> menus = menuMapper.selectMenusByRoleId(roleId);
return menus.stream()
.filter(menu -> StringUtils.isNotEmpty(menu.getAuthority()))
.map(SysMenu::getAuthority)
.distinct()
.collect(Collectors.toList());
}
```
### 权限分配流程
```java
// 分配角色菜单权限
@PostMapping("/assignRoleMenus")
public AjaxResult assignRoleMenus(@RequestBody Map<String, Object> params) {
Integer roleId = (Integer) params.get("roleId");
List<Integer> menuIds = (List<Integer>) params.get("menuIds");
// 删除原有权限
sysRoleMenuMapper.delete(
new LambdaQueryWrapper<SysRoleMenu>()
.eq(SysRoleMenu::getRoleId, roleId)
);
// 添加新权限
for (Integer menuId : menuIds) {
SysRoleMenu roleMenu = new SysRoleMenu();
roleMenu.setRoleId(roleId);
roleMenu.setMenuId(menuId);
sysRoleMenuMapper.insert(roleMenu);
}
return AjaxResult.success("分配成功");
}
```
## 总结
这个问题的根本原因是系统使用基于角色的权限管理,而不是基于用户的权限管理。当修改权限时,影响的是整个角色,而不是单个用户。通过界面改进,现在用户可以清楚地了解权限管理机制和影响范围。