RBAC 模型的簡單實現

RBAC 模型基本介紹

RBAC(Role-Based Access Control,基于角色的訪問控制)是一種廣泛應用的權限管理模型。它的核心思想是通過角色來管理權限,而不是直接分配權限給用戶。用戶被賦予一個或多個角色,而每個角色擁有不同的權限。

RBAC 的核心組件

用戶(User):系統的使用者。
角色(Role):一組權限的集合。
權限(Permission):對系統資源的具體操作(如讀、寫、刪除等)。
用戶-角色分配(User-Role Assignment):將用戶與角色關聯。
角色-權限分配(Role-Permission Assignment):將角色與權限關聯。

RBAC 的工作流程

  1. 管理員定義角色(如管理員、編輯、訪客)。
  2. 為每個角色分配相應的權限(如管理員可以讀寫,訪客只能讀)。
  3. 將用戶分配到相應的角色。
  4. 用戶通過角色間接獲得權限

舉例:

場景:
存在某系統,系統包含 1 ~ 10 個菜單目錄,現在用戶群體 A 需要擁有 1~3 的菜單權限,用戶群體 B 需要擁有 3~5 菜單的權限,用戶群體 C 需要擁有 6~10 的菜單權限…


RBAC 處理方式:

  1. 系統管理員定義角色,為用戶群體 A 創建角色 A1,A1包含 1~3 的菜單權限,為用戶群里 B 創建角色 A2…
  2. 將角色分配到不同用戶群體。
  3. 不同用戶根據分配到的角色,間接獲得系統的部分權限。

RBAC 優缺點

優點

  1. 簡化權限管理:通過角色間接分配權限,減少了直接管理用戶權限的復雜性。
  2. 易于擴展:新增用戶只需分配角色,無需重新定義權限。
  3. 支持最小權限原則:可以為角色分配最小必要的權限,降低安全風險。
  4. 適合多用戶系統:在企業級應用中,RBAC 可以很好地支持復雜的權限需求。

缺點

  1. 角色爆炸問題:當角色過多時,管理角色本身會變得復雜。
  2. 靈活性不足:對于需要動態權限的場景(如基于時間、地點的權限),RBAC 的支持較弱。
  3. 權限粒度有限:RBAC 的權限控制通常是粗粒度的,難以實現細粒度的權限控制。

RBAC 的實現

數據庫設計

圖中由左至右,依次為:菜單表、菜單-角色對應表、角色表、角色-用戶對應表、用戶表;
菜單表和角色表之間為多對多關系;
角色表和用戶表之間為多對多關系;
在這里插入圖片描述

后端實現(SpringBoot + SaToken)

    @PostMapping("/addMenu")  @Operation(summary = "新增菜單")@SaCheckPermission("system:menu:add")   // 只有用戶含有該權限標識符,才會放行請求,否則拋出異常public ResponseResult addMenu(@Validated @RequestBody MenuForm menuForm) {log.info("addMenu:{}", menuForm);menuService.addMenu(menuForm, StpUtil.getLoginId().toString());return ResponseResult.ok().message("添加成功");}

SaCheckPermission實現原理

/** SaToken 處理邏輯 **/public void checkPermissionAnd(String... permissionArray){// 先獲取當前是哪個賬號idObject loginId = getLoginId();// 如果沒有指定權限,那么直接跳過if(permissionArray == null || permissionArray.length == 0) {return;}// 獲取該用戶的所有權限List<String> permissionList = getPermissionList(loginId);for (String permission : permissionArray) {// 判斷該權限是否在該用戶的權限列表中,若不存在,則拋出 NotPermissionException 異常if(!hasElement(permissionList, permission)) {throw new NotPermissionException(permission, this.loginType).setCode(SaErrorCode.CODE_11051);}}}

前端實現

/** 前端動態路由 **/
const dynamicRoutesFromBackend = (backendRoutes: MenuEntity[]): RouteType[] => {// 輔助函數:如果路徑以 '/' 開頭,則去掉 '/'const normalizePath = (path?: string): string => {return path && path.startsWith('/') ? path.slice(1) : path || ''; // 確保路徑存在后再處理};// 生成動態路由const dynamicChildren: RouteType[] = [];backendRoutes.filter(route => route.status === 1).forEach(route => {if (route.menuType === 'M') {const normalizedPath = normalizePath(route.path);if (normalizedPath && !route.children) {dynamicChildren.push({path: normalizedPath,element: withLoadingComponent(lazy(() =>(modules[`/src/views/${normalizedPath}/index.tsx`]?.().then((module) => ({ default: (module as { default: React.ComponentType }).default })))  // 類型斷言|| import('../views/Error').then((module) => ({ default: (module as { default: React.ComponentType }).default })))),children: []});}if (!route.path && route.children) {route.children.forEach(childRoute => {const normalizedChildPath = normalizePath(childRoute.path);dynamicChildren.push({path: normalizedChildPath,element: withLoadingComponent(lazy(() =>modules[`/src/views/${normalizedChildPath}/index.tsx`]? (modules[`/src/views/${normalizedChildPath}/index.tsx`] as () => Promise<{ default: React.ComponentType }> )()  // 使用類型斷言并確保返回 Promise<{ default: React.ComponentType }>: import('../views/Error').then((mod) => ({ default: mod.default }))  // 錯誤頁面的處理)),children: []});});}}});
/**動態加載菜單**/
function covertRoutesToMenuItems(routes: RouteType[]): MenuItem[] {// 查找 path 為 '/' 的根路由const rootRoute = routes.find(route => route.path === '/');if (!rootRoute || !rootRoute.children) {return [];}// 遞歸解析子路由const convertToMenu = (routeList: RouteType[]): MenuItem[] => {return routeList.filter(route => !route.hidden) // 過濾掉 hidden 為 true 的路由.map(route => ({key: route.path,label: route.name,icon: route.icon,children: route.children ? convertToMenu(route.children) : undefined,  // 遞歸處理子菜單}));};// 開始處理 '/' 的子路由return convertToMenu(rootRoute.children);
}

完整代碼

前端完整代碼地址 : Gitee
后端完整代碼地址 : Gitee

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/72325.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/72325.shtml
英文地址,請注明出處:http://en.pswp.cn/web/72325.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數據結構---堆棧和列

一、堆棧 1.棧堆&#xff1a;具有一定操作約束的線性表&#xff1b;&#xff08;只在一端做插入刪除&#xff09; 2.棧的順序存儲結構&#xff1a; 由一個一維數組和一個記錄棧頂元素位置的變量組成。定義方式如下&#xff1a; 3.入棧操作&#xff1a; 注意&#xff1a;&…

2023 年全國職業院校技能大賽(中職組)移動應用與開發賽項 賽題第十套

2023 年全國職業院校技能大賽&#xff08;中職組&#xff09;移動應用與開發賽項 賽題第十套&#xff09; 移動應用與開發賽項競賽模塊 A&#xff1a;移動應用界面設計任務 1 環保中心界面設計&#xff08;7.5 分&#xff09;任務 2&#xff1a;首頁界面設計&#xff08;7.5 分…

FPGA為何要盡量減少組合邏輯的使用

在FPGA設計中&#xff0c;組合邏輯的使用確實需要謹慎&#xff0c;尤其是要盡量減少它的復雜性。這并不是因為組合邏輯本身不好&#xff0c;而是因為它在實際應用中容易引發一系列問題&#xff0c;而這些問題往往與FPGA的設計哲學和硬件特性相沖突。讓我從幾個關鍵點來和你聊聊…

c語言筆記 字符串函數---strcmp,strncmp,strchr,strrchr

目錄 函數strcmp與strncmp 以下是錯誤的示范&#xff1a;兩個指針字符型的指針不能直接進行比較 函數strchr與函數strrchr 函數strchr與函數strrchr與strstr函數三者對比 背景&#xff1a;如果說我們要比較兩個字符串是否相等&#xff0c;使用strcmp或者strncmp函數。在c語言中…

合React寶寶體質的自定義節流hook

本文為開發開源項目的真實開發經歷&#xff0c;感興趣的可以來給我的項目點個star&#xff0c;謝謝啦~ 具體博文介紹&#xff1a; 開源&#xff5c;Documind協同文檔&#xff08;接入deepseek-r1、支持實時聊天&#xff09;Documind &#x1f680; 一個支持實時聊天和接入 - 掘…

【RTSP】客戶端(五)H264 265處理邏輯

H264處理邏輯 整體邏輯分析 實現邏輯 解析 RTP 包頭&#xff1a;首先檢查 RTP 頭部的有效負載類型&#xff08;payloadType&#xff09;是否匹配處理擴展頭&#xff1a;如果 RTP 包包含擴展頭&#xff0c;跳過擴展頭部分&#xff0c;獲取有效負載處理分片數據&#xff1a;H264…

IDEA集成git,項目的克隆,遠程倉庫中文件的添加刪除

目錄 一、克隆項目 二、使用IDEA完成文件的上傳和刪除 1.配置git 2.上傳 3.刪除&#xff08;通過git bash&#xff09; 一、克隆項目 點擊克隆&#xff0c;復制url &#xff0c;如下 打開你想要克隆到哪里&#xff0c;右擊&#xff0c;選擇 open Git Bash here 這一步之后…

神經網絡:定義與核心原理

神經網絡&#xff08;Artificial Neural Network, ANN&#xff09;是一種受生物神經系統啟發的計算模型&#xff0c;旨在通過模擬神經元之間的連接與信息傳遞機制&#xff0c;實現復雜的數據處理和模式識別功能。其本質是由大量簡單處理單元&#xff08;神經元&#xff09;構成…

將pdf或者word轉換成base64格式

廢話不多說直接上代碼&#xff1a; function fileToBase64(file) {return new Promise((resolve, reject) > {const reader new FileReader();reader.readAsDataURL(file);reader.onload function (event) {const base64Data event.target.result.split(,)[1];resolve(b…

Spring @Bean注解使用場景二

bean:最近在寫一篇讓Successfactors顧問都能搞明白的sso的邏輯的文章&#xff0c;所以一致在研究IAS的saml2.0的協議&#xff0c;希望用代碼去解釋SP、idp的一些概念&#xff0c;讓顧問了解SSO與saml的關系&#xff0c;在github找代碼的時候發現一些代碼的調用關系很難理解&…

ubuntu22.04 關于掛在設備為nfts文件格式無法創建軟連接的問題

最近遇到情況&#xff0c;解壓工程報錯&#xff0c;無法創建軟連接 但是盤內還有130G空間&#xff0c;明顯不是空間問題&#xff0c;查找之后發現是移動硬盤的文件格式是NTFS&#xff0c;在ubuntu上不好兼容&#xff0c;于是報錯。 開貼記錄解決方案。 1.確定文件格式 使用命…

docker后臺運行,便于后期用命令行進入它的終端

在 docker compose up --build -d 命令中&#xff0c;?**-d?&#xff08;或 --detach&#xff09;參數的作用是讓容器以后臺模式&#xff08;detached mode&#xff09;?**運行。以下是詳細解釋&#xff1a; ?**-d 參數的作用** ?后臺運行容器&#xff1a; 默認情況下&a…

網頁制作14-Javascipt時間特效の顯示動態日期

<!doctype html> <html> <head> <meta charset"utf-8"> <title>動態日期</title> </head><script>var today new Date();//獲取時間var ytoday.getFullYear();//截取年var mtoday.getMonth();//截取月份,返回0~11v…

【BP神經網絡】實戰

1.參考Python實戰&#xff1a;BP神經網絡_bp神經網絡實戰python-CSDN博客 2.實踐 &#xff08;1&#xff09;運行環境 anocanda Powershell Prompt&#xff08;anocanda3&#xff09; &#xff08;2&#xff09;創建虛擬環境&#xff0c;解決安裝包的版本問題 *打開終端&a…

深度學習多模態人臉情緒識別:從理論到實踐

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到網站。https://www.captainbed.cn/north 文章目錄 1. 引言2. 技術框架與流程圖3. 核心算法解析3.1 視覺特征提取&#xff08;CNN&#xff09;3.2…

ssh通過22端口無法連接服務器問題處理

一&#xff0c;安全組開放22端口 root無法連接服務器&#xff0c;22端口也開放了&#xff0c;可能是防火墻開啟了攔截。 二&#xff0c;檢測防火墻狀態 查看防火墻狀態 sudo firewall-cmd --state 關閉防火墻 sudo systemctl stop firewalld 開啟防火墻 sudo systemctl sta…

element 的tab怎么動態根據參數值添加一個vue頁面

在使用 Element UI 的 Tabs 組件時&#xff0c;動態添加 Vue 組件或頁面可以通過操作 tabs 數組來實現。假設你要根據參數值來動態添加一個 Vue 頁面&#xff08;這里假設是一個 Vue 組件&#xff09;&#xff0c;你可以按照以下步驟操作&#xff1a; 首先&#xff0c;確保你已…

Docker封裝鏡像、分發、部署實踐:nginx

在實際生產工作中&#xff0c;通常是沒法直接訪問公網的&#xff0c;但是有經常需要使用Docker部署應用&#xff0c;本文將介紹使用Docker從拉取nginx、打包、分發到加載部署nginx的全流程&#xff01; 1 準備工作 1.1 安裝docker 請參考&#xff1a;Docker入門指南&#xff…

LuaJIT 學習(5)—— string.buffer 庫

文章目錄 Using the String Buffer LibraryBuffer ObjectsBuffer Method Overview Buffer Creation and Managementlocal buf buffer.new([size [,options]]) local buf buffer.new([options])buf buf:reset()buf buf:free() Buffer Writersbuf buf:put([str|num|obj] [,……