跳转到主要内容

菜单权限

本页面展示了一个使用 jCasbin 实现基于菜单的访问控制的 Spring Boot 示例。同样的模式(policy + 角色分配 + 菜单层级)也可以应用到 Casbin 支持的其他语言中。

1. 配置​

在 policy.csv 中定义角色—菜单权限、用户—角色分配以及菜单层级。完整示例:jCasbin menu permission。

1.1 概览​

policy 文件定义了:(1) 哪些角色可以访问哪些菜单项,(2) 哪些用户拥有哪些角色,(3) 菜单项之间的父子关系。这些组合起来就实现了基于角色的、带层级的菜单可见性。

1.2 权限规则(p)​

以 p 开头的行定义了某个角色(sub)是否可以对某个菜单项(obj)执行某个操作(act)。effect(eft)为 allow 或 deny。

示例:

  • p, ROLE_ROOT, SystemMenu, read, allow 授予 ROLE_ROOT 对 SystemMenu 的 read 权限。
  • p, ROLE_ROOT, UserMenu, read, deny 拒绝 ROLE_ROOT 对 UserMenu 的 read 权限。

1.3 用户—角色分配(g)​

以 g 开头的行把用户分配给角色,并定义角色继承。用户会获得其所有角色权限的并集。

示例:

  • g, user, ROLE_USER 把名为 user 的用户分配给 ROLE_USER。
  • g, ROLE_ADMIN, ROLE_USER 使 ROLE_ADMIN 继承 ROLE_USER 的所有权限。

1.4 菜单层级(g2)​

以 g2 开头的行定义菜单的父子结构。

示例:

  • g2, UserSubMenu_allow, UserMenu 使 UserSubMenu_allow 成为 UserMenu 的子菜单。
  • g2, (NULL), SystemMenu 将 SystemMenu 标记为没有父级的顶级菜单。

1.5 菜单权限继承​

  • 如果某个父菜单显式 allow,那么它的子菜单会继承 allow,除非某个子菜单显式 deny。也就是说,允许父菜单即允许其子菜单。
  • 如果父菜单没有显式权限,但至少有一个子菜单 allow,则父菜单被视为 allow,以便用户能够访问到该子菜单。

1.6 拒绝与角色继承​

  • 显式拒绝优先:如果一个角色被显式拒绝访问某个菜单,那么任何继承自它的角色同样被拒绝。拒绝不会被继承所覆盖。
  • 隐式拒绝(没有 allow 规则)是可以被覆盖的:更高权限的角色可以为该菜单添加显式的 allow。

1.7 示例 policy​

p, ROLE_ROOT, SystemMenu, read, allow
p, ROLE_ROOT, AdminMenu, read, allow
p, ROLE_ROOT, UserMenu, read, deny
p, ROLE_ADMIN, UserMenu, read, allow
p, ROLE_ADMIN, AdminMenu, read, allow
p, ROLE_ADMIN, AdminSubMenu_deny, read, deny
p, ROLE_USER, UserSubMenu_allow, read, allow

g, user, ROLE_USER
g, admin, ROLE_ADMIN
g, root, ROLE_ROOT
g, ROLE_ADMIN, ROLE_USER

g2, UserSubMenu_allow, UserMenu
g2, UserSubMenu_deny, UserMenu
g2, UserSubSubMenu, UserSubMenu_allow
g2, AdminSubMenu_allow, AdminMenu
g2, AdminSubMenu_deny, AdminMenu
g2, (NULL), SystemMenu
MenuNameROLE_ROOTROLE_ADMINROLE_USER
SystemMenu✅❌❌
UserMenu❌✅❌
UserSubMenu_allow❌✅✅
UserSubSubMenu❌✅✅
UserSubMenu_deny❌✅❌
AdminMenu✅✅❌
AdminSubMenu_allow✅✅❌
AdminSubMenu_deny✅❌❌

2. 菜单权限的执行​

在 jCasbin menu permission 示例中,MenuService 提供了 findAccessibleMenus()(用户可以看到的所有菜单)和 checkMenuAccess()(检查单个菜单)。二者底层都使用 jCasbin enforcer。