Menu Permissions
This guide demonstrates a Spring Boot application that implements menu-based access control using jCasbin. The approach shown here serves as a foundation for building menu permission middleware that can be adapted to other Casbin-supported languages like Go and Python.
1. 配置文件
Configure role permissions and menu hierarchies in the policy.csv file. For a complete working example, see the jCasbin menu permission repository.
1.1 概述
The policy.csv file enables granular access control by defining role-based permissions for menu items, user-role assignments, and hierarchical menu structures. This configuration combines three elements: which roles can access which menu items, which users belong to which roles, and how menus relate to each other in the navigation hierarchy.
1.2 权限定义(策略)
- Policy Rules: Each policy line starts with
pand defines whether a role (sub) has permission to perform an action (act) on a menu item (obj). The effect (eft) is eitherallowordeny.
示例:
p, ROLE_ROOT, SystemMenu, read, allowgrantsROLE_ROOTread access toSystemMenu.p, ROLE_ROOT, UserMenu, read, denydeniesROLE_ROOTread access toUserMenu.
1.3 角色和用户关联
- Role Inheritance: Lines starting with
gdefine user-role assignments and role inheritance chains. Users automatically inherit permissions from all their assigned roles.
示例:
g, user, ROLE_USERassigns the user namedusertoROLE_USER.g, ROLE_ADMIN, ROLE_USERmakesROLE_ADMINinherit all permissions fromROLE_USER.
1.4 菜单项层次结构
- Menu Relationships: Lines starting with
g2define parent-child relationships between menu items, establishing the menu structure.
示例:
g2, UserSubMenu_allow, UserMenumakesUserSubMenu_allowa child ofUserMenu.g2, (NULL), SystemMenumarksSystemMenuas a top-level menu with no parent.
1.5 菜单权限继承和默认规则
jCasbin applies specific inheritance rules when determining menu access based on parent-child relationships:
父菜单权限的继承:
When a parent menu has explicit allow permission, all child menus inherit allow by default unless explicitly set to deny. Granting access to a parent menu automatically grants access to its children.
处理没有 直接权限设置的父菜单:
When a parent menu has no explicit permission but contains at least one child menu with explicit allow permission, the parent menu is implicitly granted allow status. This ensures users can reach the accessible child menus.
1.6 特殊权限继承规则
Role inheritance interacts with deny permissions according to these rules:
明确拒绝和默认拒绝的区别:
Explicit deny permissions always take precedence. When a role like ROLE_ADMIN is explicitly denied access to AdminSubMenu_deny, no role that inherits from ROLE_ADMIN (such as ROLE_ROOT) can access that menu. Explicit denials cannot be overridden through role inheritance.
默认拒绝权限的继承:
Default denials (menus that lack an explicit allow) work differently. When UserSubMenu_deny is implicitly denied to ROLE_USER simply because no allow rule exists, a role inheriting from ROLE_USER (like ROLE_ADMIN) can override this by adding its own explicit allow rule.
1.7 示例描述
策略:
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
| 菜单名称 | ROLE_ROOT | ROLE_ADMIN | ROLE_USER |
|---|---|---|---|
| SystemMenu | ✅ | ❌ | ❌ |
| UserMenu | ❌ | ✅ | ❌ |
| UserSubMenu_allow | ❌ | ✅ | ✅ |
| UserSubSubMenu | ❌ | ✅ | ✅ |
| UserSubMenu_deny | ❌ | ✅ | ❌ |
| AdminMenu | ✅ | ✅ | ❌ |
| AdminSubMenu_allow | ✅ | ✅ | ❌ |
| AdminSubMenu_deny | ✅ | ❌ | ❌ |
2. 菜单权限控制
Use findAccessibleMenus() from MenuService to retrieve all menu items a user can access. To verify access to a specific menu item, call the checkMenuAccess() method. These functions provide efficient menu permission enforcement through jCasbin's access control engine.