115 lines
3.6 KiB
Markdown
115 lines
3.6 KiB
Markdown
|
|
# 超级管理员权限说明
|
|||
|
|
|
|||
|
|
## 问题原因
|
|||
|
|
|
|||
|
|
超级管理员(15900000000)的操作权限没有全部打开的原因是:
|
|||
|
|
|
|||
|
|
### 1. **权限管理基于角色,而非超级管理员特权**
|
|||
|
|
|
|||
|
|
当前系统使用**基于角色的权限管理(RBAC)**:
|
|||
|
|
- 权限存储在 `sys_role_menu` 表中
|
|||
|
|
- 所有使用相同 `roleId` 的用户共享相同的权限
|
|||
|
|
- 即使 `roleId=1`(超级管理员角色),也要遵循数据库中的权限配置
|
|||
|
|
|
|||
|
|
### 2. **超级管理员权限标识**
|
|||
|
|
|
|||
|
|
系统在代码层面为超级管理员提供了特殊处理:
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
// StpInterfaceImpl.java 第38-42行
|
|||
|
|
if (roleId.equals(RoleConstants.SUPER_ADMIN_ROLE_ID)) {
|
|||
|
|
log.info("用户 {} 是超级管理员,拥有所有权限", loginId);
|
|||
|
|
// 超级管理员返回通配符权限
|
|||
|
|
return Collections.singletonList(RoleConstants.ALL_PERMISSION);
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
这意味着:
|
|||
|
|
- **后端验证**:超级管理员拥有 `*:*:*` 权限,后端不会拦截任何操作
|
|||
|
|
- **前端显示**:但前端界面的复选框状态取决于数据库中的 `sys_role_menu` 表
|
|||
|
|
|
|||
|
|
### 3. **权限界面的作用**
|
|||
|
|
|
|||
|
|
"操作权限管理"界面中的复选框状态:
|
|||
|
|
- ✅ **不影响功能权限**:只是用于展示和编辑数据库中的权限配置
|
|||
|
|
- ✅ **超级管理员仍然可以操作**:即使复选框未选中,后端也会允许访问
|
|||
|
|
- ⚠️ **前端按钮显示受影响**:如果权限未勾选,前端 `v-hasPermi` 指令会隐藏按钮
|
|||
|
|
|
|||
|
|
## 解决方案
|
|||
|
|
|
|||
|
|
### 方案1:为超级管理员角色分配所有权限(推荐)
|
|||
|
|
|
|||
|
|
在数据库中为 `roleId=1` 分配所有菜单权限:
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
-- 查询所有菜单ID
|
|||
|
|
SELECT id FROM sys_menu WHERE is_delete = 0;
|
|||
|
|
|
|||
|
|
-- 为超级管理员角色分配所有菜单权限
|
|||
|
|
-- 假设有 100 个菜单,IDs 为 1-100
|
|||
|
|
INSERT INTO sys_role_menu (role_id, menu_id)
|
|||
|
|
SELECT 1, id FROM sys_menu WHERE is_delete = 0
|
|||
|
|
ON DUPLICATE KEY UPDATE role_id = role_id;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 方案2:前端特殊处理超级管理员
|
|||
|
|
|
|||
|
|
修改前端的权限检查逻辑,让超级管理员始终显示所有按钮:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// src/utils/permission.js 或类似的权限检查文件
|
|||
|
|
const hasPermission = (permission) => {
|
|||
|
|
const userStore = useUserStore();
|
|||
|
|
const isSuperAdmin = userStore.roleId === 1; // 超级管理员 roleId=1
|
|||
|
|
|
|||
|
|
if (isSuperAdmin) {
|
|||
|
|
return true; // 超级管理员直接返回 true
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 普通用户的权限检查逻辑
|
|||
|
|
// ...
|
|||
|
|
};
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 方案3:完全忽略前端权限检查(不推荐)
|
|||
|
|
|
|||
|
|
对于超级管理员,可以跳过所有前端权限检查,但这可能带来安全隐患。
|
|||
|
|
|
|||
|
|
## 建议
|
|||
|
|
|
|||
|
|
**最佳实践**:
|
|||
|
|
1. 在数据库中为超级管理员角色(roleId=1)分配所有菜单权限
|
|||
|
|
2. 前端保留权限检查逻辑(安全考虑)
|
|||
|
|
3. 后端继续使用 `*:*:*` 特殊处理
|
|||
|
|
|
|||
|
|
这样既保证了超级管理员的功能完整性,又保持了权限管理的规范性。
|
|||
|
|
|
|||
|
|
## 如何判断超级管理员是否有权限
|
|||
|
|
|
|||
|
|
### 前端权限检查(影响按钮显示)
|
|||
|
|
|
|||
|
|
```vue
|
|||
|
|
<!-- 如果权限未勾选,按钮会被隐藏 -->
|
|||
|
|
<el-button v-hasPermi="['loading:edit']">编辑</el-button>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 后端权限验证(实际控制)
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
// 即使前端按钮显示,后端也会验证
|
|||
|
|
@SaCheckPermission("loading:edit")
|
|||
|
|
public AjaxResult editOrder(...) {
|
|||
|
|
// 超级管理员 roleId=1 会被自动放行
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 总结
|
|||
|
|
|
|||
|
|
**超级管理员的操作权限没有全部打开**是因为:
|
|||
|
|
1. 数据库中的 `sys_role_menu` 表没有为超级管理员角色分配所有菜单
|
|||
|
|
2. 前端的复选框显示基于数据库配置
|
|||
|
|
3. 但这**不影响**后端功能权限:超级管理员仍然可以访问所有接口
|
|||
|
|
|
|||
|
|
**解决方案**:为超级管理员角色在数据库中分配所有菜单权限即可。
|
|||
|
|
|