CRM權限管理
有興趣的同學也可以閱讀我最近分享的:Shiro框架原理分析 (PS : 這篇博客里面介紹了使用Shiro框架的方式實現權限管理)
https://www.cnblogs.com/yly-blog/p/9837384.html
如果發現分享的內容有不合理或者的不對地方,請留言,我會及時定位分析,感謝!!!
一、概念
權限管理就是管理用戶對於資源的操作。本 CRM 系統的權限(也稱作資源)是基於角色操作權限來實現的,即RBAC(Role-Based Access Control,基於角色的訪問控制),就是用戶通過角色與權限進行關聯。簡單地說,一個用戶擁有若干角色,每一個角色擁有若干權限。這樣,就構造成“用戶-角色-權限”的授權模型。在這種模型中,用戶與角色之間,角色與權限之間都是多對多的關系,為了實現表之間多對多的關系,必須將一個多對多的關系通過一個中間表分為兩個一對多的關系。因此引入中間表,用戶角色表和角色權限表。
二、數據庫
權限管理模塊一共涉及五張表:
- 三張主表
a) 用戶表(t_user)、
b) 角色表(t_role)、
c) 資源表(t_module)、
2.兩張中間表
a) 用戶角色表(t_user_role)、
b) 角色—資源表(t_permission)、
三、權限管理實現
1、模塊、角色、用戶的單表CRUD
模塊CRUD:操作t_module表
角色CRUD:操作t_role表
用戶CRUD:操作t_role表
2、授權
角色賦予權限
給角色賦予權限:使用ztree進行權限樹結構的構建
a)賦權限
1、先把本模塊綁定;
2、綁定父模塊;
3、綁定子模塊
b)刪權限
1、先刪除本模塊;
2、刪除子模塊;
3、刪除父模塊(判斷父模塊是否有其他的子模塊關聯詞角色,如果沒有就取消,如果有就關聯)
a) 使用jQuery的插件zTree構建一個資源的樹結構,樹中的內容為表t_module中的數據
b) 用鼠標點擊zTree中的選擇框操作表t_permission(角色資源表)實現給角色賦予權限
用戶賦予角色
給用戶賦予角色:使用的combobox多選
a).添加賬號:直接往t_user_role插入記錄
b).修改賬號:先刪除,在添加
創建用戶或者是修改用戶信息時都可以通過combobox多選框給用戶賦予角色操作t_user_role(用戶角色表)
3、認證
思路:
從t_permission表中獲取權限值(acl_value)與頁面傳來的值或者與注解中明確的權限值比較,下面提供兩種思路:
1.頁面傳遞過來Request.getParameter(“permission”);比對 根據userId查詢數據庫查到的權限列表 contains
2.通過注解明確模塊權限值:@requirePermission(permission=”1010”;
后台認證:Spring AOP和自定義注解實現認證
獲取用戶權限存入session,然后用戶操作資源時會提交一個資源的權限值,在判斷用戶是否包含有此權限
使用Spring AOP進行攔截認證
第一步:開啟注解驅動<aop:aspectj-autoproxy />
第二步:創建一個代理類使用@Aspect @Component注解進行標記
第三步:定義一個切入點@Pointcut(" *execution('com.shsxt.controller.*.*((..))')")
public void pointcut() {}
第四步:編寫一個增強:@Around(value="pointcut()")
1.判定用戶是否登錄
2.獲取用戶權限
3.將權限存入session--》給前端頁面判斷
4.后台的權限校驗
5.返回
- 自定義注解
2.編寫切面類
定義切入點point:自攔截有權限注解的方法,更能提升性能
//@Pointcut("execution(* com.shsxt.controller.*.*(..))") @Pointcut("@annotation(com.shsxt.annotation.RequirePermissions)") public void pointcut() { }
通過前台傳遞permission參數實現:
List<String> permissions = permissionService.findRolePermissions(roleIds.substring(0, roleIds.lastIndexOf(","))); String permissioFront = request.getParameter("permission"); // 后台權限認證 AssertUtil.isTrue(!permissions.contains(permissioFront), "您無權操作此模塊");
通過注解實現
List<String> permissions = permissionService.findRolePermissions(roleIds.substring(0, roleIds.lastIndexOf(","))); if (requirePermissions != null) { String permission = requirePermissions.permission(); // 后台權限認證 throw new UnAuthPermissionException(permission, "您無權操作此模塊"); }
3.引入AOP的namepsace並開啟AOP注解驅動
<!-- 啟用@Aspect注解 --> <aop:aspectj-autoproxy />
4.在需要權限認證的方法上啟用注解
Permission應該和module表中的act_value保持一致
前台認證:Freemarker 內建函數判斷
獲取用戶權限后在前端的freemarker中利用freemarker語法去判斷用戶是否能夠操作此資源(list?seq_contains('權限值'))
1.SQL:
SELECT DISTINCT p.acl_value FROM t_permission p -- LEFT JOIN t_role r ON r.id = ur.role_id left JOIN t_user_role ur on p.role_id = ur.role_id WHERE ur.user_id = 10;
2.在AOP切面類中查詢permission取出權限值列表、放入Session
3.前台頁面判斷: 解釋:利用freemarker 內建函數sql_contains判斷序列是否包含參數值,包含返回true
類似於java中集合hashmap.contains(value);