Files
cattleTransportation/pc-cattle-transportation/SUPER_ADMIN_PERMISSION_EXPLANATION.md
2025-10-27 17:38:20 +08:00

3.6 KiB
Raw Blame History

超级管理员权限说明

问题原因

超级管理员15900000000的操作权限没有全部打开的原因是

1. 权限管理基于角色,而非超级管理员特权

当前系统使用基于角色的权限管理RBAC

  • 权限存储在 sys_role_menu 表中
  • 所有使用相同 roleId 的用户共享相同的权限
  • 即使 roleId=1(超级管理员角色),也要遵循数据库中的权限配置

2. 超级管理员权限标识

系统在代码层面为超级管理员提供了特殊处理:

// 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 分配所有菜单权限:

-- 查询所有菜单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前端特殊处理超级管理员

修改前端的权限检查逻辑,让超级管理员始终显示所有按钮:

// 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. 后端继续使用 *:*:* 特殊处理

这样既保证了超级管理员的功能完整性,又保持了权限管理的规范性。

如何判断超级管理员是否有权限

前端权限检查(影响按钮显示)

<!-- 如果权限未勾选按钮会被隐藏 -->
<el-button v-hasPermi="['loading:edit']">编辑</el-button>

后端权限验证(实际控制)

// 即使前端按钮显示,后端也会验证
@SaCheckPermission("loading:edit")
public AjaxResult editOrder(...) {
    // 超级管理员 roleId=1 会被自动放行
}

总结

超级管理员的操作权限没有全部打开是因为:

  1. 数据库中的 sys_role_menu 表没有为超级管理员角色分配所有菜单
  2. 前端的复选框显示基于数据库配置
  3. 但这不影响后端功能权限:超级管理员仍然可以访问所有接口

解决方案:为超级管理员角色在数据库中分配所有菜单权限即可。