天天看點

RBAC基于角色的權限管理--設計篇1.0RBAC基于角色的權限管理–設計篇1.0

RBAC基于角色的權限管理–設計篇1.0

RBAC是什麼

基于角色的權限管理。簡單來說就是一個使用者可以擁有若幹個角色,一個角色可以擁有若幹個權限。這樣就形成了“使用者-角色-權限”的模型。

基礎表設計

  • 資料庫采用MySql
  • 這裡表設計隻采用最基礎的字段
  • 忽略字段長度,如采用此設計,請自行修改
  • 忽略外鍵建設,如采用此設計,請自行建立

使用者表

CREATE TABLE `t_user` (
  `id` int() NOT NULL AUTO_INCREMENT COMMENT
  `create_time` datetime DEFAULT NULL COMMENT '建立時間',
  `create_user` datetime DEFAULT NULL COMMENT '建立人',
  `login_time` datetime DEFAULT NULL COMMENT '登入時間',
  `name` varchar() DEFAULT NULL COMMENT '使用者名稱',
  `password` varchar() DEFAULT NULL COMMENT '登入密碼',
  `remark` varchar() DEFAULT NULL COMMENT '備注',
  `status` int() DEFAULT NULL COMMENT '使用者狀态',
  `update_time` datetime DEFAULT NULL COMMENT '更新時間',
  `update_user` datetime DEFAULT NULL COMMENT '更新人員',
  `username` varchar() DEFAULT NULL COMMENT '登入名稱',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT= DEFAULT CHARSET=utf8;
           

角色表

CREATE TABLE `t_role` (
  `id` int() NOT NULL AUTO_INCREMENT COMMENT '角色id',
  `role_name` varchar() DEFAULT NULL COMMENT '角色名稱',
  `remark` varchar() DEFAULT NULL COMMENT '備注',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT= DEFAULT CHARSET=utf8;
           

權限表

CREATE TABLE `t_permission` (
  `id` int() NOT NULL AUTO_INCREMENT COMMENT '權限ID',
  `permission_code` varchar() DEFAULT NULL COMMENT '權限編碼',
  `permission_name` varchar() DEFAULT NULL COMMENT '權限名稱',
  `pid` int() DEFAULT NULL COMMENT '父類權限ID(依賴權限)',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT= DEFAULT CHARSET=utf8;
           

使用者角色關系表

CREATE TABLE `t_user_role` (
  `user_id` int() NOT NULL COMMENT '使用者id',
  `role_id` int() NOT NULL COMMENT '角色id',
  PRIMARY KEY (`user_id`,`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
           

角色權限關系表

CREATE TABLE `t_role_permission` (
  `role_id` int() NOT NULL COMMENT '角色id',
  `permission_id` int() NOT NULL COMMENT '權限id',
  PRIMARY KEY (`role_id`,`permission_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
           

權限控制

控制菜單

場景

管理者和普通會員。如管理者可以看到所有菜單,普通會員隻能看到一部分菜單(或可以看到,但點選時彈出沒有權限操作的提示。由于個人喜好和個人體驗度偏差的原因,此文章中不采取這種方式)。

問題來了,如何控制角色的菜單權限?let‘s go!!!

表設計

CREATE TABLE `t_menu` (
  `id` int() NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',
  `menu_name` varchar() DEFAULT NULL COMMENT '菜單名稱',
  `permission_code` varchar() DEFAULT NULL COMMENT '權限編碼(菜單編碼)',
  `pid` int() DEFAULT NULL COMMENT '父菜單id',
  `url` varchar() DEFAULT NULL COMMENT '菜單url跳轉連結',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT= DEFAULT CHARSET=utf8;
           

簡要業務流程圖

RBAC基于角色的權限管理--設計篇1.0RBAC基于角色的權限管理–設計篇1.0

詳細業務流程圖

RBAC基于角色的權限管理--設計篇1.0RBAC基于角色的權限管理–設計篇1.0

控制按鈕

場景

擁有了菜單權限,依舊不能滿足某些場景的需要。例如多個角色在同時擁有A菜單的情況下,角色1可以有查詢,建立的權限,角色2則擁有查詢,建立,修改,删除的權限。即角色1隻能看到查詢,建立的按鈕,角色2可以看到查詢,建立,修改,删除的按鈕。這個時候,我們應該如何處理呢?

實作

  • 按鈕權限定義:在菜單權限下定義下級權限查詢,建立,修改,删除,例如Aquery,Aadd,Aupdate,Adelete。
  • 這裡結合shiro使用(不會使用的小夥伴請留言,後期補上解決方式):在A菜單跳轉的頁面中使用則可以達到控制按鈕的效果。例如
    <shiro:hasPermission name="Aadd">
            <button>建立<button>
        </shiro:hasPermission> 
               

詳細業務流程圖(結合shiro)

RBAC基于角色的權限管理--設計篇1.0RBAC基于角色的權限管理–設計篇1.0

代碼示例(思想很重要)

檢查使用者是否有菜單權限
/**
 * 檢查使用者是否有菜單權限
 * 
 * @param menus
 *            所有菜單
 * @param subject
 *            shiro使用者資訊
 * @return 使用者已配置設定的菜單集合
 */
private List<Menu> check(List<Menu> menus, Subject subject) {
    List<Menu> res = new ArrayList<Menu>();
    for (Menu m1 : menus) {
        if (StringUtils.isEmpty(m1.getPermissionCode())) {
            continue;
        }
        // 這裡會觸發鑒權操作
        if (subject.isPermitted(m1.getPermissionCode())) {
            res.add(m1);
        }
    }
    return res;
}
           
自定義realm-鑒權操作
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    // 查詢目前使用者所有權限
    List<Permission> infos = userService.findMyPermitions();
    // 權限集合(這裡我習慣把權限編碼放進去)
    Set<String> permissions = new HashSet<String>();
    // 角色集合(這裡放角色ID)
    Set<String> roles = new HashSet<String>();
    if (infos != null && infos.size() > ) {
        for (Permission info : infos) {
            permissions.add(info.getPermissionCode());
            roles.add(info.getRoleId());
        }
    }
    SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
    authorizationInfo.setStringPermissions(permissions);
    authorizationInfo.setRoles(roles);
    return authorizationInfo;
}
           

資料權限

場景

有些業務可能會是這樣。一個清單(或表格),要求普通使用者隻能看到自己建立的清單資訊,業務部門經理隻能看到本部門的所有清單資訊。這種權限如何控制?

實作

看留言反應,下回見。