整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          SpringBoot系列-Security + Layui實現一套權限管理后臺模板

           前言

            Spring Security官網:https://spring.io/projects/spring-security

            Spring Security是一個功能強大且高度可定制的身份驗證和訪問控制框架,側重于為Java應用程序提供身份驗證和授權。Security通過大量的攔截器進行校驗,具體請看官網列出的列表:https://docs.spring.io/spring-security/site/docs/4.2.4.RELEASE/reference/htmlsingle/#ns-custom-filters

            本文記錄在SpringBoot項目中整合Spring Security進行權限控制,配合Layui,實現一套相對簡單的權限管理后臺模板


            效果演示

            登錄,一個簡單的登錄頁面,沒登錄之前,訪問任意接口都會被攔截到登錄頁面(本例中,密碼沒有進行加密,存儲的是明文,大家自己再進行加密存儲跟校驗,我這樣就從簡了)

            我們可以利用配置文件的分支選擇,設置開發環境不進行驗證碼校驗,測試、生產環境再開啟驗證碼校驗,這樣可以大大方便我們開發調試

            xxx_huanzi,普通用戶權限登錄

            xxx_sa、xxx_admin,管理員權限登錄

            退出登錄

            關鍵代碼

            數據表

            首先我們要確定下我們需要哪些表,結構跟測試數據我一起貼出來

            系統用戶表

          SET NAMES utf8mb4;
          SET FOREIGN_KEY_CHECKS = 0;
          
          -- ----------------------------
          -- Table structure for sys_user
          -- ----------------------------
          DROP TABLE IF EXISTS `sys_user`;
          CREATE TABLE `sys_user`  (
            `user_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用戶id',
            `login_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '登錄名',
            `user_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用戶名稱',
            `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '登錄密碼',
            `valid` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '軟刪除標識,Y/N',
            `limited_ip` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '限制允許登錄的IP集合',
            `limited_mac` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '更高級別的安全限制,限制允許登錄的mac地址集合',
            `expired_time` datetime NULL DEFAULT NULL COMMENT '賬號失效時間,超過時間將不能登錄系統',
            `last_change_pwd_time` datetime NOT NULL COMMENT '最近修改密碼時間,超出時間間隔,提示用戶修改密碼',
            `limit_multi_login` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '是否允許賬號同一個時刻多人在線,Y/N',
            `greate_time` datetime NOT NULL COMMENT '創建時間',
            `update_time` datetime NOT NULL COMMENT '修改時間',
            PRIMARY KEY (`user_id`) USING BTREE
          ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '系統用戶表' ROW_FORMAT = Compact;
          
          -- ----------------------------
          -- Records of sys_user
          -- ----------------------------
          INSERT INTO `sys_user` VALUES ('1', 'xxx_sa', 'sa', '123456', 'Y', NULL, NULL, '2020-09-01 16:35:16', '2019-07-19 16:35:46', 'N', '2019-07-19 16:36:03', '2019-07-19 16:36:07');
          INSERT INTO `sys_user` VALUES ('2', 'xxx_admin', 'admin', '123456', 'Y', NULL, NULL, '2020-09-01 16:35:16', '2019-07-19 16:35:46', 'N', '2019-07-19 16:36:03', '2019-07-19 16:36:07');
          INSERT INTO `sys_user` VALUES ('3', 'xxx_huanzi', 'huanzi', '123456', 'Y', NULL, NULL, '2020-09-01 16:35:16', '2019-07-19 16:35:46', 'N', '2019-07-19 16:36:03', '2019-07-19 16:36:07');
          
          SET FOREIGN_KEY_CHECKS = 1;

            系統權限表

          SET NAMES utf8mb4;
          SET FOREIGN_KEY_CHECKS = 0;
          
          -- ----------------------------
          -- Table structure for sys_authority
          -- ----------------------------
          DROP TABLE IF EXISTS `sys_authority`;
          CREATE TABLE `sys_authority`  (
            `authority_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '權限id',
            `authority_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '權限名稱,ROLE_開頭,全大寫',
            `authority_remark` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '權限描述',
            PRIMARY KEY (`authority_id`) USING BTREE
          ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '系統權限表' ROW_FORMAT = Compact;
          
          -- ----------------------------
          -- Records of sys_authority
          -- ----------------------------
          INSERT INTO `sys_authority` VALUES ('1', 'ROLE_SA', '超級管理員權限');
          INSERT INTO `sys_authority` VALUES ('2', 'ROLE_ADMIN', '管理員權限');
          INSERT INTO `sys_authority` VALUES ('3', 'ROLE_USER', '普通用戶權限');
          
          SET FOREIGN_KEY_CHECKS = 1;

            系統菜單表

          SET NAMES utf8mb4;
          SET FOREIGN_KEY_CHECKS = 0;
          
          -- ----------------------------
          -- Table structure for sys_menu
          -- ----------------------------
          DROP TABLE IF EXISTS `sys_menu`;
          CREATE TABLE `sys_menu`  (
            `menu_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '菜單id',
            `menu_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '菜單名稱',
            `menu_path` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '菜單路徑',
            `menu_parent_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '上級id',
            PRIMARY KEY (`menu_id`) USING BTREE
          ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '系統菜單表' ROW_FORMAT = Compact;
          
          -- ----------------------------
          -- Records of sys_menu
          -- ----------------------------
          INSERT INTO `sys_menu` VALUES ('1', '系統管理', '/sys', NULL);
          INSERT INTO `sys_menu` VALUES ('2', '用戶管理', '/sys/user', '1');
          INSERT INTO `sys_menu` VALUES ('3', '權限管理', '/sys/authority', '1');
          INSERT INTO `sys_menu` VALUES ('4', '菜單管理', '/sys/menu', '1');
          INSERT INTO `sys_menu` VALUES ('5', 'XXX菜單', '/menu/xxx', '');
          INSERT INTO `sys_menu` VALUES ('6', 'XXX菜單1', '/menu/xxx1', '5');
          INSERT INTO `sys_menu` VALUES ('7', 'XXX菜單2', '/menu/xxx2', '5');
          
          SET FOREIGN_KEY_CHECKS = 1;

            用戶與權限關聯表

          SET NAMES utf8mb4;
          SET FOREIGN_KEY_CHECKS = 0;
          
          -- ----------------------------
          -- Table structure for sys_user_authority
          -- ----------------------------
          DROP TABLE IF EXISTS `sys_user_authority`;
          CREATE TABLE `sys_user_authority`  (
            `user_authority_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用戶權限表id',
            `user_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用戶id',
            `authority_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '權限id',
            PRIMARY KEY (`user_authority_id`) USING BTREE
          ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用戶權限表' ROW_FORMAT = Compact;
          
          -- ----------------------------
          -- Records of sys_user_authority
          -- ----------------------------
          INSERT INTO `sys_user_authority` VALUES ('1', '1', '1');
          INSERT INTO `sys_user_authority` VALUES ('2', '2', '2');
          INSERT INTO `sys_user_authority` VALUES ('3', '3', '3');
          
          SET FOREIGN_KEY_CHECKS = 1;

            用戶與菜單關聯表

          SET NAMES utf8mb4;
          SET FOREIGN_KEY_CHECKS = 0;
          
          -- ----------------------------
          -- Table structure for sys_user_menu
          -- ----------------------------
          DROP TABLE IF EXISTS `sys_user_menu`;
          CREATE TABLE `sys_user_menu`  (
            `user_menu_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用戶菜單表id',
            `user_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用戶id',
            `menu_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '菜單id',
            PRIMARY KEY (`user_menu_id`) USING BTREE
          ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用戶菜單表' ROW_FORMAT = Compact;
          
          -- ----------------------------
          -- Records of sys_user_menu
          -- ----------------------------
          INSERT INTO `sys_user_menu` VALUES ('1', '1', '1');
          INSERT INTO `sys_user_menu` VALUES ('10', '3', '6');
          INSERT INTO `sys_user_menu` VALUES ('11', '3', '7');
          INSERT INTO `sys_user_menu` VALUES ('2', '1', '2');
          INSERT INTO `sys_user_menu` VALUES ('3', '1', '3');
          INSERT INTO `sys_user_menu` VALUES ('4', '1', '4');
          INSERT INTO `sys_user_menu` VALUES ('41', '1', '5');
          INSERT INTO `sys_user_menu` VALUES ('42', '1', '6');
          INSERT INTO `sys_user_menu` VALUES ('43', '1', '7');
          INSERT INTO `sys_user_menu` VALUES ('5', '2', '1');
          INSERT INTO `sys_user_menu` VALUES ('51', '2', '5');
          INSERT INTO `sys_user_menu` VALUES ('52', '2', '6');
          INSERT INTO `sys_user_menu` VALUES ('53', '2', '7');
          INSERT INTO `sys_user_menu` VALUES ('6', '2', '2');
          INSERT INTO `sys_user_menu` VALUES ('7', '2', '3');
          INSERT INTO `sys_user_menu` VALUES ('8', '2', '4');
          INSERT INTO `sys_user_menu` VALUES ('9', '3', '5');
          
          SET FOREIGN_KEY_CHECKS = 1;

            用戶快捷菜單表

          SET NAMES utf8mb4;
          SET FOREIGN_KEY_CHECKS = 0;
          
          -- ----------------------------
          -- Table structure for sys_shortcut_menu
          -- ----------------------------
          DROP TABLE IF EXISTS `sys_shortcut_menu`;
          CREATE TABLE `sys_shortcut_menu`  (
            `shortcut_menu_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用戶快捷菜單id',
            `shortcut_menu_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用戶快捷菜單名稱',
            `shortcut_menu_path` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用戶快捷菜單路徑',
            `user_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用戶id',
            `shortcut_menu_parent_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '上級id',
            PRIMARY KEY (`shortcut_menu_id`) USING BTREE
          ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用戶快捷菜單表' ROW_FORMAT = Compact;
          
          -- ----------------------------
          -- Records of sys_shortcut_menu
          -- ----------------------------
          INSERT INTO `sys_shortcut_menu` VALUES ('s1', '百度', 'https://www.baidu.com', '2', NULL);
          INSERT INTO `sys_shortcut_menu` VALUES ('s2', 'layui', 'https://www.layui.com/', '3', NULL);
          
          SET FOREIGN_KEY_CHECKS = 1;

            大家可能會發現我們的系統用戶表有很多字段,又是限制IP地址、又是限制Mac地址,這是基于安全性考慮,系統可以能會限制用戶的登錄地址, 這些字段都是一下安全性方面相關,但在這個例子了我并沒有實現這些功能,大家可以沿著我的這個思路實現一下系統安全性功能


            maven引包

            Spring Boot提供了一個spring-boot-starter-security啟動程序,它將Spring Security相關的依賴項聚合在一起,使用maven引入

                  <!-- security安全校驗 -->
                  <dependency>
                      <groupId>org.springframework.boot</groupId>
                      <artifactId>spring-boot-starter-security</artifactId>
                  </dependency>

            生成后臺代碼

            引好包后,使用我們的通用后臺接口與代碼自動生成工具,運行main方法直接生成這六個表的后臺代碼(不知道怎么操作的請看我之前的博客:SpringBoot系列——Spring-Data-JPA(究極進化版) 自動生成單表基礎增、刪、改、查接口)


            核心配置

            核心配置在SecurityConfig

            由此也擴展出了用戶認證處理、密碼處理、登錄成功處理、登錄失敗處理、驗證碼處理、errorPage處理,這些我就不貼出來了,大家自己去看代碼 

          package cn.huanzi.qch.springbootsecurity.config;
          
          import org.springframework.beans.factory.annotation.Autowired;
          import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
          import org.springframework.security.config.annotation.web.builders.HttpSecurity;
          import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
          import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
          import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
          
          @EnableWebSecurity
          public class SecurityConfig extends WebSecurityConfigurerAdapter {
          
              @Autowired
              private CaptchaFilterConfig captchaFilterConfig;
          
              @Autowired
              private UserConfig userConfig;
          
              @Autowired
              private PasswordConfig passwordConfig;
          
              @Autowired
              private LoginFailureHandlerConfig loginFailureHandlerConfig;
          
              @Autowired
              private LoginSuccessHandlerConfig loginSuccessHandlerConfig;
          
              @Override
              protected void configure(AuthenticationManagerBuilder auth) throws Exception {
                  auth
                          //用戶認證處理
                          .userDetailsService(userConfig)
                          //密碼處理
                          .passwordEncoder(passwordConfig);
              }
          
              @Override
              protected void configure(HttpSecurity http) throws Exception {
                  http
                          // 關閉csrf防護
                          .csrf().disable()
                          .headers().frameOptions().disable()
                          .and()
          
                          //定制url訪問權限
                          .authorizeRequests()
                          .antMatchers("/layui/**", "/css/**", "/js/**", "/images/**", "/webjars/**", "/getVerifyCodeImage").permitAll()
                          //系統相關、非業務接口只能是管理員以上有權限,例如獲取系統權限接口、系統用戶接口、系統菜單接口、以及用戶與權限、菜單關聯接口
                          .antMatchers("/sysUser/**","/sysAuthority/**","/sysMenu/**","/sysUserAuthority/**","/sysUserMenu/**").hasAnyAuthority("ROLE_ADMIN","ROLE_SA")
                          //admin接口測試
                          .antMatchers("/admin/**").hasAnyAuthority("ROLE_ADMIN","ROLE_SA")
                          .anyRequest().authenticated()
                          .and()
          
                          //登錄處理
                          .addFilterBefore(captchaFilterConfig, UsernamePasswordAuthenticationFilter.class)
                          .formLogin()
                          .loginProcessingUrl("/login")
                          .loginPage("/loginPage")
                          .failureHandler(loginFailureHandlerConfig)
                          .successHandler(loginSuccessHandlerConfig)
                          .permitAll()
                          .and()
          
                          //登出處理
                          .logout()
                          .logoutUrl("/logout")
                          .logoutSuccessUrl("/loginPage")
                          .permitAll()
                  ;
              }
          }

            后記

            這只是一個簡單的演示,數據都是直接在數據庫插入的,應該做成在頁面進行管理,比如:

            更多的功能我就不展開了,大家直接進行擴展,本文就記錄到這,有什么問題以后再進行補充,具體的代碼已經放到GitHub、碼云上了,SQL文件我也放在了里面,


            大家可以搞下來跑一下,有什么建議或者問題都可以評論留言


            代碼開源

            代碼已經開源、托管到我的GitHub、碼云:

            GitHub:https://github.com/huanzi-qch/springBoot

            碼云:https://gitee.com/huanzi-qch/springBoot


          版權聲明

          作者:huanzi-qch

          出處:https://www.cnblogs.com/huanzi-qch

          若標題中有“轉載”字樣,則本文版權歸原作者所有。若無轉載字樣,本文版權歸作者所有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,否則保留追究法律責任的權利.

          作者:iceblow
          來源:https://www.cnblogs.com/iceblow/p/11121362.html
          

          限系統設計

          前言

          權限管理是所有后臺系統的都會涉及的一個重要組成部分,主要目的是對不同的人訪問資源進行權限的控制,避免因權限控制缺失或操作不當引發的風險問題,如操作錯誤,隱私數據泄露等問題。

          目前在公司負責權限這塊,所以對權限這塊的設計比較熟悉,公司采用微服務架構,權限系統自然就獨立出來了,其他業務系統包括商品中心,訂單中心,用戶中心,倉庫系統,小程序,多個APP等十幾個系統和終端

          1.權限模型

          迄今為止最為普及的權限設計模型是RBAC模型,基于角色的訪問控制(Role-Based Access Control)

          1.1 RBAC0模型

          RBAC0模型如下:

          這是權限最基礎也是最核心的模型,它包括用戶/角色/權限,其中用戶和角色是多對多的關系,角色和權限也是多對多的關系。

          用戶是發起操作的主體,按類型分可分為2B和2C用戶,可以是后臺管理系統的用戶,可以是OA系統的內部員工,也可以是面向C端的用戶,比如阿里云的用戶。

          角色起到了橋梁的作用,連接了用戶和權限的關系,每個角色可以關聯多個權限,同時一個用戶關聯多個角色,那么這個用戶就有了多個角色的多個權限。有人會問了為什么用戶不直接關聯權限呢?在用戶基數小的系統,比如20個人的小系統,管理員可以直接把用戶和權限關聯,工作量并不大,選擇一個用戶勾選下需要的權限就完事了。但是在實際企業系統中,用戶基數比較大,其中很多人的權限都是一樣的,就是個普通訪問權限,如果管理員給100人甚至更多授權,工作量巨大。這就引入了"角色(Role)"概念,一個角色可以與多個用戶關聯,管理員只需要把該角色賦予用戶,那么用戶就有了該角色下的所有權限,這樣設計既提升了效率,也有很大的拓展性。

          權限是用戶可以訪問的資源,包括頁面權限,操作權限,數據權限:

          • 頁面權限: 即用戶登錄系統可以看到的頁面,由菜單來控制,菜單包括一級菜單和二級菜單,只要用戶有一級和二級菜單的權限,那么用戶就可以訪問頁面
          • 操作權限: 即頁面的功能按鈕,包括查看,新增,修改,刪除,審核等,用戶點擊刪除按鈕時,后臺會校驗用戶角色下的所有權限是否包含該刪除權限,如果是,就可以進行下一步操作,反之提示無權限。有的系統要求"可見即可操作",意思是如果頁面上能夠看到操作按鈕,那么用戶就可以操作,要實現此需求,這里就需要前端來配合,前端開發把用戶的權限信息緩存,在頁面判斷用戶是否包含此權限,如果有,就顯示該按鈕,如果沒有,就隱藏該按鈕。某種程度上提升了用戶體驗,但是在實際場景可自行選擇是否需要這樣做
          • 數據權限: 數據權限就是用戶在同一頁面看到的數據是不同的,比如財務部只能看到其部門下的用戶數據,采購部只看采購部的數據,在一些大型的公司,全國有很多城市和分公司,比如杭州用戶登錄系統只能看到杭州的數據,上海用戶只能看到上海的數據,解決方案一般是把數據和具體的組織架構關聯起來,舉個例子,再給用戶授權的時候,用戶選擇某個角色同時綁定組織如財務部或者合肥分公司,那么該用戶就有了該角色下財務部或合肥分公司下的的數據權限。


          以上是RBAC的核心設計及模型分析,此模型也叫做RBAC0,而基于核心概念之上,RBAC還提供了擴展模式。包括RBAC1,RBAC2,RBAC3模型。下面介紹這三種類型

          1.2 RBAC1模型

          此模型引入了角色繼承(Hierarchical Role)概念,即角色具有上下級的關系,角色間的繼承關系可分為一般繼承關系和受限繼承關系。一般繼承關系僅要求角色繼承關系是一個絕對偏序關系,允許角色間的多繼承。而受限繼承關系則進一步要求角色繼承關系是一個樹結構,實現角色間的單繼承。這種設計可以給角色分組和分層,一定程度簡化了權限管理工作。

          1.3 RBAC2模型

          基于核心模型的基礎上,進行了角色的約束控制,RBAC2模型中添加了責任分離關系,其規定了權限被賦予角色時,或角色被賦予用戶時,以及當用戶在某一時刻激活一個角色時所應遵循的強制性規則。責任分離包括靜態責任分離和動態責任分離。主要包括以下約束:

          • 互斥角色: 同一用戶只能分配到一組互斥角色集合中至多一個角色,支持責任分離的原則。互斥角色是指各自權限互相制約的兩個角色。比如財務部有會計和審核員兩個角色,他們是互斥角色,那么用戶不能同時擁有這兩個角色,體現了職責分離原則
          • 基數約束: 一個角色被分配的用戶數量受限;一個用戶可擁有的角色數目受限;同樣一個角色對應的訪問權限數目也應受限,以控制高級權限在系統中的分配
          • 先決條件角色: 即用戶想獲得某上級角色,必須先獲得其下一級的角色

          1.4 RBAC3模型

          即最全面的權限管理,它是基于RBAC0,將RBAC1和RBAC2進行了整合

          1.5 用戶組

          當平臺用戶基數增大,角色類型增多時,而且有一部分人具有相同的屬性,比如財務部的所有員工,如果直接給用戶分配角色,管理員的工作量就會很大,如果把相同屬性的用戶歸類到某用戶組,那么管理員直接給用戶組分配角色,用戶組里的每個用戶即可擁有該角色,以后其他用戶加入用戶組后,即可自動獲取用戶組的所有角色,退出用戶組,同時也撤銷了用戶組下的角色,無須管理員手動管理角色。

          根據用戶組是否有上下級關系,可以分為有上下級的用戶組和普通用戶組:

          • 具有上下級關系的用戶組: 最典型的例子就是部門和職位,可能多數人沒有把部門職位和用戶組關聯起來吧。當然用戶組是可以拓展的,部門和職位常用于內部的管理系統,如果是面向C端的系統,比如淘寶網的商家,商家自身也有一套組織架構,比如采購部,銷售部,客服部,后勤部等,有些人擁有客服權限,有些人擁有上架權限等等,所以用戶組是可以拓展的
          • 普通用戶組: 即沒有上下級關系,和組織架構,職位都沒有關系,也就是說可以跨部門,跨職位,舉個例子,某電商后臺管理系統,有拼團活動管理角色,我們可以設置一個拼團用戶組,該組可以包括研發部的后臺開發人員,運營部的運營人員,采購部的人員等等。

          每個公司都會涉及到到組織和職位,下面就重點介紹這兩個。

          1.5.1 組織

          常見的組織架構如下圖:

          我們可以把組織與角色進行關聯,用戶加入組織后,就會自動獲得該組織的全部角色,無須管理員手動授予,大大減少工作量,同時用戶在調崗時,只需調整組織,角色即可批量調整。組織的另外一個作用是控制數據權限,把角色關聯到組織,那么該角色只能看到該組織下的數據權限。

          1.5.2 職位

          假設財務部的職位如下圖:

          每個組織部門下都會有多個職位,比如財務部有總監,會計,出納等職位,雖然都在同一部門,但是每個職位的權限是不同的,職位高的擁有更多的權限。總監擁有所有權限,會計和出納擁有部分權限。特殊情況下,一個人可能身兼多職。

          1.6 含有組織/職位/用戶組的模型

          根據以上場景,新的權限模型就可以設計出來了,如下圖:

          根據系統的復雜度不同,其中的多對多關系和一對一關系可能會有變化,

          • 在單系統且用戶類型單一的情況下,用戶和組織是一對一關系,組織和職位是一對多關系,用戶和職位是一對一關系,組織和角色是一對一關系,職位和角色是一對一關系,用戶和用戶組是多對對關系,用戶組和角色是一對一關系,當然這些關系也可以根據具體業務進行調整。模型設計并不是死的,如果小系統不需要用戶組,這塊是可以去掉的。
          • 分布式系統且用戶類型單一的情況下,到這里權限系統就會變得很復雜,這里就要引入了一個"系統"概念,此時系統架構是個分布式系統,權限系統獨立出來,負責所有的系統的權限控制,其他業務系統比如商品中心,訂單中心,用戶中心,每個系統都有自己的角色和權限,那么權限系統就可以配置其他系統的角色和權限。
          • 分布式系統且用戶類型多個的情況下,比如淘寶網,它的用戶類型包括內部用戶,商家,普通用戶,內部用戶登錄多個后臺管理系統,商家登錄商家中心,這些做權限控制,如果你作為架構師,該如何來設計呢?大神可以在評論區留言交流哦!

          2.授權流程

          授權即給用戶授予角色,按流程可分為手動授權和審批授權。權限中心可同時配置這兩種,可提高授權的靈活性。

          • 手動授權: 管理員登錄權限中心為用戶授權,根據在哪個頁面授權分為兩種方式:給用戶添加角色,給角色添加用戶。給用戶添加角色就是在用戶管理頁面,點擊某個用戶去授予角色,可以一次為用戶添加多個角色;給角色添加用戶就是在角色管理頁面,點擊某個角色,選擇多個用戶,實現了給批量用戶授予角色的目的。
          • 審批授權: 即用戶申請某個職位角色,那么用戶通過OA流程申請該角色,然后由上級審批,該用戶即可擁有該角色,不需要系統管理員手動授予。

          3.表結構

          有了上述的權限模型,設計表結構就不難了,下面是多系統下的表結構,簡單設計下,主要提供思路:

          4.權限框架

          • Apache Shrio
          • Spring Security

          在項目中可以采用其中一種框架,它們的優缺點以及如何使用會在后面的文章中詳細介紹.

          5.結語

          權限系統可以說是整個系統中最基礎,同時也可以很復雜的,在實際項目中,會遇到多個系統,多個用戶類型,多個使用場景,這就需要具體問題具體分析,但最核心的RBAC模型是不變的,我們可以在其基礎上進行擴展來滿足需求。

          最后,如果您覺得這篇文章對您有幫助,可以點個贊,謝謝支持!

          者:iceblow

          鏈接:https://www.cnblogs.com/iceblow/p/11121362.html

          前言

          權限管理是所有后臺系統的都會涉及的一個重要組成部分,主要目的是對不同的人訪問資源進行權限的控制,避免因權限控制缺失或操作不當引發的風險問題,如操作錯誤,隱私數據泄露等問題。

          1、權限模型

          迄今為止最為普及的權限設計模型是RBAC模型,基于角色的訪問控制(Role-Based Access Control)

          1.1 RBAC0模型

          RBAC0模型如下:

          這是權限最基礎也是最核心的模型,它包括用戶/角色/權限,其中用戶和角色是多對多的關系,角色和權限也是多對多的關系。

          用戶是發起操作的主體,按類型分可分為2B和2C用戶,可以是后臺管理系統的用戶,可以是OA系統的內部員工,也可以是面向C端的用戶,比如阿里云的用戶。

          角色起到了橋梁的作用,連接了用戶和權限的關系,每個角色可以關聯多個權限,同時一個用戶關聯多個角色,那么這個用戶就有了多個角色的多個權限。有人會問了為什么用戶不直接關聯權限呢?在用戶基數小的系統,比如20個人的小系統,管理員可以直接把用戶和權限關聯,工作量并不大,選擇一個用戶勾選下需要的權限就完事了。但是在實際企業系統中,用戶基數比較大,其中很多人的權限都是一樣的,就是個普通訪問權限,如果管理員給100人甚至更多授權,工作量巨大。這就引入了"角色(Role)"概念,一個角色可以與多個用戶關聯,管理員只需要把該角色賦予用戶,那么用戶就有了該角色下的所有權限,這樣設計既提升了效率,也有很大的拓展性。

          權限是用戶可以訪問的資源,包括頁面權限,操作權限,數據權限:


          • 頁面權限: 即用戶登錄系統可以看到的頁面,由菜單來控制,菜單包括一級菜單和二級菜單,只要用戶有一級和二級菜單的權限,那么用戶就可以訪問頁面
          • 操作權限: 即頁面的功能按鈕,包括查看,新增,修改,刪除,審核等,用戶點擊刪除按鈕時,后臺會校驗用戶角色下的所有權限是否包含該刪除權限,如果是,就可以進行下一步操作,反之提示無權限。有的系統要求"可見即可操作",意思是如果頁面上能夠看到操作按鈕,那么用戶就可以操作,要實現此需求,這里就需要前端來配合,前端開發把用戶的權限信息緩存,在頁面判斷用戶是否包含此權限,如果有,就顯示該按鈕,如果沒有,就隱藏該按鈕。某種程度上提升了用戶體驗,但是在實際場景可自行選擇是否需要這樣做
          • 數據權限: 數據權限就是用戶在同一頁面看到的數據是不同的,比如財務部只能看到其部門下的用戶數據,采購部只看采購部的數據,在一些大型的公司,全國有很多城市和分公司,比如杭州用戶登錄系統只能看到杭州的數據,上海用戶只能看到上海的數據,解決方案一般是把數據和具體的組織架構關聯起來,舉個例子,再給用戶授權的時候,用戶選擇某個角色同時綁定組織如財務部或者合肥分公司,那么該用戶就有了該角色下財務部或合肥分公司下的的數據權限。

          以上是RBAC的核心設計及模型分析,此模型也叫做RBAC0,而基于核心概念之上,RBAC還提供了擴展模式。包括RBAC1,RBAC2,RBAC3模型。下面介紹這三種類型


          1.2 RBAC1模型

          此模型引入了角色繼承(Hierarchical Role)概念,即角色具有上下級的關系,角色間的繼承關系可分為一般繼承關系和受限繼承關系。一般繼承關系僅要求角色繼承關系是一個絕對偏序關系,允許角色間的多繼承。而受限繼承關系則進一步要求角色繼承關系是一個樹結構,實現角色間的單繼承。這種設計可以給角色分組和分層,一定程度簡化了權限管理工作。


          1.3 RBAC2模型


          基于核心模型的基礎上,進行了角色的約束控制,RBAC2模型中添加了責任分離關系,其規定了權限被賦予角色時,或角色被賦予用戶時,以及當用戶在某一時刻激活一個角色時所應遵循的強制性規則。責任分離包括靜態責任分離和動態責任分離。主要包括以下約束:


          • 互斥角色: 同一用戶只能分配到一組互斥角色集合中至多一個角色,支持責任分離的原則。互斥角色是指各自權限互相制約的兩個角色。比如財務部有會計和審核員兩個角色,他們是互斥角色,那么用戶不能同時擁有這兩個角色,體現了職責分離原則
          • 基數約束: 一個角色被分配的用戶數量受限;一個用戶可擁有的角色數目受限;同樣一個角色對應的訪問權限數目也應受限,以控制高級權限在系統中的分配
          • 先決條件角色: 即用戶想獲得某上級角色,必須先獲得其下一級的角色


          1.4 RBAC3模型


          即最全面的權限管理,它是基于RBAC0,將RBAC1和RBAC2進行了整合


          1.5 用戶組


          當平臺用戶基數增大,角色類型增多時,而且有一部分人具有相同的屬性,比如財務部的所有員工,如果直接給用戶分配角色,管理員的工作量就會很大,如果把相同屬性的用戶歸類到某用戶組,那么管理員直接給用戶組分配角色,用戶組里的每個用戶即可擁有該角色,以后其他用戶加入用戶組后,即可自動獲取用戶組的所有角色,退出用戶組,同時也撤銷了用戶組下的角色,無須管理員手動管理角色。


          • 具有上下級關系的用戶組: 最典型的例子就是部門和職位,可能多數人沒有把部門職位和用戶組關聯起來吧。當然用戶組是可以拓展的,部門和職位常用于內部的管理系統,如果是面向C端的系統,比如淘寶網的商家,商家自身也有一套組織架構,比如采購部,銷售部,客服部,后勤部等,有些人擁有客服權限,有些人擁有上架權限等等,所以用戶組是可以拓展的
          • 普通用戶組: 即沒有上下級關系,和組織架構,職位都沒有關系,也就是說可以跨部門,跨職位,舉個例子,某電商后臺管理系統,有拼團活動管理角色,我們可以設置一個拼團用戶組,該組可以包括研發部的后臺開發人員,運營部的運營人員,采購部的人員等等。

          每個公司都會涉及到到組織和職位,下面就重點介紹這兩個。

          1.5.1 組織

          常見的組織架構如下圖:

          我們可以把組織與角色進行關聯,用戶加入組織后,就會自動獲得該組織的全部角色,無須管理員手動授予,大大減少工作量,同時用戶在調崗時,只需調整組織,角色即可批量調整。組織的另外一個作用是控制數據權限,把角色關聯到組織,那么該角色只能看到該組織下的數據權限。

          1.5.2 職位

          假設財務部的職位如下圖:

          每個組織部門下都會有多個職位,比如財務部有總監,會計,出納等職位,雖然都在同一部門,但是每個職位的權限是不同的,職位高的擁有更多的權限。總監擁有所有權限,會計和出納擁有部分權限。特殊情況下,一個人可能身兼多職。

          1.6 含有組織/職位/用戶組的模型

          根據以上場景,新的權限模型就可以設計出來了,如下圖:


          根據系統的復雜度不同,其中的多對多關系和一對一關系可能會有變化,


          • 在單系統且用戶類型單一的情況下,用戶和組織是一對一關系,組織和職位是一對多關系,用戶和職位是一對一關系,組織和角色是一對一關系,職位和角色是一對一關系,用戶和用戶組是多對對關系,用戶組和角色是一對一關系,當然這些關系也可以根據具體業務進行調整。模型設計并不是死的,如果小系統不需要用戶組,這塊是可以去掉的。
          • 分布式系統且用戶類型單一的情況下,到這里權限系統就會變得很復雜,這里就要引入了一個"系統"概念,此時系統架構是個分布式系統,權限系統獨立出來,負責所有的系統的權限控制,其他業務系統比如商品中心,訂單中心,用戶中心,每個系統都有自己的角色和權限,那么權限系統就可以配置其他系統的角色和權限。
          • 分布式系統且用戶類型多個的情況下,比如淘寶網,它的用戶類型包括內部用戶,商家,普通用戶,內部用戶登錄多個后臺管理系統,商家登錄商家中心,這些做權限控制,如果你作為架構師,該如何來設計呢?大神可以在評論區留言交流哦

          2、授權流程

          授權即給用戶授予角色,按流程可分為手動授權和審批授權。權限中心可同時配置這兩種,可提高授權的靈活性。


          • 手動授權: 管理員登錄權限中心為用戶授權,根據在哪個頁面授權分為兩種方式:給用戶添加角色,給角色添加用戶。給用戶添加角色就是在用戶管理頁面,點擊某個用戶去授予角色,可以一次為用戶添加多個角色;給角色添加用戶就是在角色管理頁面,點擊某個角色,選擇多個用戶,實現了給批量用戶授予角色的目的。
          • 審批授權: 即用戶申請某個職位角色,那么用戶通過OA流程申請該角色,然后由上級審批,該用戶即可擁有該角色,不需要系統管理員手動授予。


          3、表結構

          有了上述的權限模型,設計表結構就不難了,下面是多系統下的表結構,簡單設計下,主要提供思路:

          4、權限框架

          • Apache Shrio
          • Spring Security


          在項目中可以采用其中一種框架,它們的優缺點以及如何使用會在后面的文章中詳細介紹.

          5、結語

          權限系統可以說是整個系統中最基礎,同時也可以很復雜的,在實際項目中,會遇到多個系統,多個用戶類型,多個使用場景,這就需要具體問題具體分析,但最核心的RBAC模型是不變的,我們可以在其基礎上進行擴展來滿足需求。


          對了,在這里說一下,我目前是在職Java開發,如果你現在正在學習Java,了解Java,渴望成為一名合格的Java開發工程師,在入門學習Java的過程當中缺乏基礎入門的視頻教程,可以關注并私信我:01。獲取。我這里有最新的Java基礎全套視頻教程。


          主站蜘蛛池模板: 午夜肉伦伦影院久久精品免费看国产一区二区三区 | 免费在线观看一区| 亚洲中文字幕一区精品自拍| 亚洲精品国产suv一区88| 伊人无码精品久久一区二区| 国产精品无码一区二区在线观 | 日韩伦理一区二区| 国产福利电影一区二区三区,免费久久久久久久精 | 中文字幕av一区| 国产成人精品无码一区二区老年人| 天天看高清无码一区二区三区 | 国产SUV精品一区二区88| 一区二区三区福利视频| 少妇特黄A一区二区三区| 国产精品99精品一区二区三区| 一区 二区 三区 中文字幕 | 国产SUV精品一区二区88L| 奇米精品一区二区三区在| 日本在线视频一区二区| 一区二区三区在线播放| 熟妇人妻AV无码一区二区三区| 国产aⅴ精品一区二区三区久久| 国产一区二区免费| 国产裸体舞一区二区三区| 99精品久久精品一区二区| 色欲AV蜜桃一区二区三| 亚洲色无码一区二区三区| 国产精品久久无码一区二区三区网 | 精品福利一区二区三区| 中文无码一区二区不卡αv| 亚洲国产一区二区视频网站| 亚洲中文字幕在线无码一区二区| 国产亚洲综合精品一区二区三区| 亚洲综合在线成人一区| 精品伦精品一区二区三区视频 | 国产在线一区观看| 无码乱码av天堂一区二区| 亚洲AV成人精品日韩一区18p| 呦系列视频一区二区三区| 亚洲AV日韩AV天堂一区二区三区| 青娱乐国产官网极品一区|