26.【.NET8 實戰--孢子記賬--從單體到微服務--轉向微服務】--單體轉微服務--角色權限管理

在現代企業級應用中,角色權限管理是保障系統安全和提升用戶體驗的核心基礎功能。一個高效的角色權限系統不僅能夠有效防止越權訪問,還能簡化系統的維護和擴展。本文將系統性介紹角色權限管理的核心實現思路,包括架構設計、性能優化、安全機制和擴展性等關鍵方面。

一、角色控制器核心實現

1.1 角色權限管理接口

控制器核心接口一共有四個方法,分別用于添加權限到角色{roleId}/permissions、獲取角色權限{roleId}/permissions、從角色中移除權限{roleId}/permissions/{permission}以及獲取用戶權限users/{userId}/permissions

具體接口說明如下:

  1. 添加權限到角色
    POST {roleId}/permissions
    用于將指定權限分配給某個角色。請求體通常包含權限標識(如字符串或權限ID)。該接口適用于管理員為角色動態分配新權限的場景。
  2. 獲取角色權限
    GET {roleId}/permissions
    查詢指定角色當前擁有的全部權限,返回權限列表。常用于權限管理界面展示、角色權限審核等場景。
  3. 從角色中移除權限
    DELETE {roleId}/permissions/{permission}
    用于撤銷某個角色的指定權限。適用于權限收回、角色權限調整等需求。
  4. 獲取用戶權限
    GET /users/{userId}/permissions
    查詢某個用戶通過其所屬角色所擁有的全部權限。該接口通常用于登錄鑒權、功能授權校驗等場景。

通過這四個核心接口,系統能夠靈活地實現角色與權限的綁定與解綁,支持權限的動態分配與回收,滿足企業級應用對權限管理的高效性和安全性要求。

二、權限服務核心實現

2.1 權限服務接口

在權限服務接口的設計中,我們圍繞角色與權限的核心業務需求,定義了四個關鍵方法,分別覆蓋了權限分配、權限回收、權限查詢等常見場景。具體如下:

  1. 添加權限到角色
    方法簽名:Task AddPermissionToRole(long roleId, string permission)
    該方法用于將指定的權限標識(如權限字符串或權限ID)分配給某個角色。通常在管理員需要為某個角色動態增加新功能權限時調用。實現時需校驗權限的有效性,并確保不會重復分配。
  2. 從角色中移除權限
    方法簽名:Task RemovePermissionFromRole(long roleId, string permission)
    該方法用于撤銷某個角色已擁有的指定權限。適用于權限調整、角色降權等場景。實現時需校驗角色與權限的綁定關系,并在移除后及時更新緩存或通知相關系統。
  3. 獲取角色權限
    方法簽名:Task<List<string>> GetPermissionsByRole(long roleId)
    該方法用于查詢指定角色當前擁有的全部權限,返回權限標識的列表。常用于權限管理后臺、角色權限審核等功能模塊。實現時可結合緩存優化查詢效率,提升系統性能。
  4. 獲取用戶權限
    方法簽名:Task<List<string>> GetUserPermissions(long userId)
    該方法用于查詢某個用戶通過其所屬角色所擁有的全部權限集合。該接口通常在用戶登錄鑒權、功能授權校驗等場景下被調用。實現時需綜合考慮用戶的多角色情況,合并去重所有角色的權限。

通過上述四個方法,權限服務接口能夠全面覆蓋角色與權限的綁定、解綁及查詢需求,為系統的權限管理提供了清晰、靈活且高效的基礎能力。這種接口設計不僅便于后續擴展(如批量分配、權限分組等),也有助于實現微服務架構下的權限統一管理和服務解耦。

2.2 權限服務實現

在本小節中,我們將詳細剖析上一小節中提到的四個核心接口(即“添加權限到角色”、“從角色中移除權限”、“獲取角色權限”、“獲取用戶權限”)的具體實現方式。我們通過對每個接口實現細節的深入講解,幫助大家全面理解角色權限管理服務的落地方案,為構建安全、靈活、可擴展的權限系統打下堅實基礎。

  1. 添加權限到角色
    添加權限到角色的方法實現,首先需要確保目標角色存在,然后將指定的權限以Claim的形式添加到該角色。如果過程中出現任何異常(如角色不存在或添加失敗),則及時拋出異常以便上層處理。具體實現如下:

    public async Task AddPermissionToRole(long roleId, string permission)
    {// 根據角色ID查找角色對象var role = await _roleManager.FindByIdAsync(roleId.ToString());if (role == null) throw new Exception("角色不存在");// 構造權限Claim對象var claim = new Claim("Permission", permission);// 嘗試將權限Claim添加到角色var result = await _roleManager.AddClaimAsync(role, claim);if (!result.Succeeded) throw new Exception("添加權限失敗");
    }
    

    該方法首先通過_roleManager.FindByIdAsync根據角色ID查找對應的角色對象,如果角色不存在則直接拋出“角色不存在”的異常。接著,利用Claim類創建一個類型為"Permission"、值為指定權限字符串的Claim對象,表示要賦予的權限。然后調用_roleManager.AddClaimAsync方法將該權限Claim添加到角色中,如果添加失敗則拋出“添加權限失敗”的異常。整個方法為異步實現,適合高并發場景,能夠保證系統的響應性能和良好的擴展性。

  2. 從角色中移除權限
    “從角色中移除權限”方法是角色權限管理中的核心操作之一,主要用于撤銷某個角色已擁有的指定權限。該方法通常應用于權限調整、角色降權、合規整改等場景,能夠確保系統權限分配的靈活性和安全性。實現思路是,首先校驗目標角色是否存在,防止對無效角色進行操作;其次構造需要移除的權限Claim對象,確保權限標識的準確性;最后調用權限管理組件(如RoleManager)的移除方法,完成權限的解綁,并對操作結果進行異常處理,保證系統的健壯性。具體實現代碼如下所示:

    public async Task RemovePermissionFromRole(long roleId, string permission)
    {// 根據角色ID查找角色對象var role = await _roleManager.FindByIdAsync(roleId.ToString());if (role == null) throw new Exception("角色不存在");// 構造要移除的權限Claim對象var claim = new Claim("Permission", permission);// 調用RoleManager移除該權限Claimvar result = await _roleManager.RemoveClaimAsync(role, claim);if (!result.Succeeded) throw new Exception("刪除權限失敗");
    }
    

    該方法首先通過_roleManager.FindByIdAsync方法,根據傳入的roleId查找對應的角色對象,如果角色不存在則拋出“角色不存在”的異常,防止后續操作出錯;然后使用Claim類構造一個類型為"Permission"、值為指定permission字符串的Claim對象,表示要移除的權限;接著調用_roleManager.RemoveClaimAsync方法,將該權限Claim從角色中移除,如果移除操作未成功則拋出“刪除權限失敗”的異常;整個方法為異步實現,能夠適應高并發場景,保證系統的性能和穩定性。

  3. 獲取角色權限
    獲取角色權限的核心思路是首先根據角色ID查找對應的角色對象,確保該角色存在;然后獲取該角色下所有的聲明(Claim)信息;接著從這些聲明中篩選出類型為"Permission"的聲明,并提取其權限標識;最后將所有權限標識整理成列表返回。這樣可以動態、準確地獲取角色當前擁有的全部權限,便于后續的權限校驗和管理。代碼如下:

    public async Task<List<string>> GetPermissionsByRole(long roleId)
    {var role = await _roleManager.FindByIdAsync(roleId.ToString());if (role == null) throw new Exception("角色不存在");var claims = await _roleManager.GetClaimsAsync(role);return claims.Where(c => c.Type == "Permission").Select(c => c.Value).ToList();
    }
    

    該方法首先通過角色ID查找對應的角色對象,如果角色不存在則拋出異常,防止后續操作出錯。隨后,調用RoleManager的GetClaimsAsync方法獲取該角色的所有聲明(Claim),并通過LINQ篩選出類型為"Permission"的聲明,提取其Value(即權限標識)。最終,將所有權限以字符串列表的形式返回。

  4. 獲取用戶權限
    獲取用戶權限的實現思路為,首先根據用戶ID查找對應的用戶對象,確保用戶存在。然后獲取該用戶所擁有的所有角色名稱。接著,遍歷每個角色,查找對應的角色對象,并獲取該角色下所有的權限聲明(Claim),篩選出類型為"Permission"的聲明并提取其權限標識。最后,將所有權限去重后以列表形式返回。這樣可以動態匯總用戶通過角色間接獲得的全部權限,便于后續的權限校驗和管理。

    public async Task<List<string>> GetUserPermissions(long userId)
    {// 根據用戶ID查找用戶對象var user = await _userManager.FindByIdAsync(userId.ToString());if (user == null) throw new Exception("用戶不存在");// 獲取用戶所屬的所有角色名稱var roles = await _userManager.GetRolesAsync(user);var permissions = new List<string>();// 遍歷每個角色,收集權限聲明foreach (var roleName in roles){var role = await _roleManager.FindByNameAsync(roleName);if (role != null){var claims = await _roleManager.GetClaimsAsync(role);permissions.AddRange(claims.Where(c => c.Type == "Permission").Select(c => c.Value));}}// 去重后返回所有權限return permissions.Distinct().ToList();
    }
    

    首先,該方法通過 _userManager.FindByIdAsync 方法,根據傳入的 userId 查找用戶對象。如果用戶不存在,則會拋出“用戶不存在”的異常,以防止后續操作出錯。接著,利用 _userManager.GetRolesAsync(user) 獲取該用戶所屬的所有角色名稱列表。隨后,創建一個空的 permissions 列表,用于收集所有權限標識。方法會遍歷每個角色名稱,使用 _roleManager.FindByNameAsync(roleName) 查找對應的角色對象。如果角色存在,則調用 _roleManager.GetClaimsAsync(role) 獲取該角色的所有聲明(Claim)。對于每個角色的聲明集合,會篩選出類型為 "Permission" 的聲明,并提取其 Value(即權限標識),將其添加到 permissions 列表中。最后,使用 Distinct() 方法對權限列表進行去重,確保同一權限不會重復出現,并以列表形式返回所有權限標識。該方法實現了用戶權限的動態聚合,能夠準確獲取用戶通過角色間接擁有的全部權限,適用于權限校驗、菜單渲染等多種業務場景。

三、總結

在本節中,我們詳細介紹了角色權限管理的核心實現思路和具體代碼實現。通過對角色權限管理接口、權限服務接口以及權限服務實現的深入剖析,我們展示了如何高效地管理角色與權限之間的關系,確保系統的安全性和靈活性。

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

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

相關文章

[VSCode] VSCode 設置 python 的編譯器

VSCode 設置 python 的編譯器 快捷鍵&#xff1a;CTRL SHIFT P 彈出 VSCode 的命令框輸入 Python : select Interpretor選擇自己需要的 python 環境&#xff1b;如 python 3.8 或者 python 3.10 版本

基于PEMFC質子交換膜燃料電池系統的simulink建模與仿真

目錄 1.課題概述 2.系統仿真結果 3.核心程序 4.系統仿真參數 5.系統原理簡介 6.參考文獻 7.完整工程文件 1.課題概述 本課題是一個燃料電池&#xff08;大概率是質子交換膜燃料電池&#xff0c;PEMFC &#xff09;的數學模型仿真框圖&#xff0c;用于模擬燃料電池的電特…

git-build-package 工具代碼詳細解讀

git-build-package&#xff08;gbp&#xff09;是一個用于從 Git 倉庫管理 Debian 軟件包的工具&#xff0c;其代碼架構和實現原理體現了對 Git 版本控制系統和 Debian 打包流程的深度整合。以下是對其代碼的詳細解讀&#xff1a; 代碼架構設計 gbp 的代碼架構設計圍繞其核心…

如何使用ChatGPT快速完成一篇論文初稿?

2小時寫完論文初稿&#xff0c;學境思源&#xff0c;聽起來是不是有點不真實&#xff1f;一鍵生成論文初稿&#xff01;但如果你有一個清晰的框架、良好的寫作節奏&#xff0c;acaids.com。再配合像ChatGPT這樣的寫作助手——真的可以做到。 這篇文章就是手把手告訴你&#xf…

Docker PowerJob

1. Docker PowerJob 1. 拉取PowerJob服務端鏡像 docker pull tjqq/powerjob-server:4.3.92. 創建數據卷目錄用于持久化數據 mkdir -p /home/docker/powerjob/logs mkdir -p /home/docker/powerjob/data mkdir -p /home/docker/powerjob/server mkdir -p /home/docker/powerjob…

Python數據可視化:NumPy生成與Matplotlib折線圖繪制

一、數據生成與可視化概述 在數據分析和科學計算領域,Python已成為最受歡迎的編程語言之一。這主要得益于其豐富的數據處理庫和強大的可視化工具。數據可視化是將抽象數據轉化為直觀圖形表示的過程,它能夠幫助我們發現數據中的模式、趨勢和異常值,從而做出更明智的決策。 …

26.多表查詢

1.笛卡爾集 創建倆表&#xff1a; -- 創建部門表&#xff08;dept&#xff09; use mysql_learn CREATE TABLE dept (deptno INT PRIMARY KEY, dname VARCHAR(50) NOT NULL, loc VARCHAR(50) );-- 創建員工表&#xff08;emp&#xff09; CREATE TABLE emp (em…

深度學習題目(僅供參考)

一、注意力和transformer 一、選擇題 注意力機制的核心步驟不包括&#xff1f; A. 計算注意力分布 B. 加權平均輸入信息 C. 隨機丟棄部分輸入 D. 打分函數計算相關性 答案&#xff1a;C&#xff08;硬性注意力雖隨機選擇輸入&#xff0c;但核心步驟仍為分布計算與加權&#xf…

WebWorker:提升前端性能的多線程利器

簡介 在現代Web開發中&#xff0c;隨著應用越來越復雜&#xff0c;JavaScript的單線程模型開始顯現其局限性。Web Workers的出現為解決這一問題提供了優雅的方案&#xff0c;它允許開發者在后臺線程中運行腳本&#xff0c;而不會影響主線程的性能。 Web Workers是HTML5標準的…

milvus教程:collection和scheme

環境配置&#xff1a;可以看上一節 一.數據庫使用 連接 Milvus Standalone創建數據庫 my_database_1&#xff08;無額外屬性&#xff09;創建數據庫 my_database_2&#xff08;設置副本數為 3&#xff09;列出所有數據庫查看默認數據庫&#xff08;default&#xff09;詳情修…

14:00開始面試,14:06就出來了,問的問題有點變態。。。

從小廠出來&#xff0c;沒想到在另一家公司又寄了。 到這家公司開始上班&#xff0c;加班是每天必不可少的&#xff0c;看在錢給的比較多的份上&#xff0c;就不太計較了。沒想到6月一紙通知&#xff0c;所有人不準加班&#xff0c;加班費不僅沒有了&#xff0c;薪資還要降40%…

Electron(01)

Electron Electron是什么 electron可以使用前端技術開發桌面應用&#xff0c;跨平臺性&#xff0c;開發一套應用&#xff0c;可以打包到三個平臺。 electron結合Chromium&#xff08;谷歌內核&#xff09;和 Node.js 和Native Api 當使用 Electron 時&#xff0c;很重要的一…

Kafka 攔截器深度剖析:原理、配置與實踐

引言 在構建高可用、可擴展的消息系統時&#xff0c;Kafka以其卓越的性能和穩定性成為眾多企業的首選。而Kafka攔截器作為Kafka生態中強大且靈活的功能組件&#xff0c;能夠在消息的生產和消費過程中實現自定義邏輯的注入&#xff0c;為消息處理流程帶來極大的擴展性和可控性。…

Flutter 與原生技術(Objective-C/Swift,java)的關系

在 iOS 開發中&#xff0c;Flutter 與原生技術&#xff08;Objective-C/Swift&#xff09;的關系 一、技術定位與核心差異 Flutter 語言&#xff1a;使用Dart 語言開發&#xff0c;通過 AOT&#xff08;提前編譯&#xff09;將代碼轉換為原生 ARM 指令&#xff0c;無需依賴 iOS…

最新期刊影響因子,基本包含全部期刊

原文鏈接&#xff1a;2024年期刊最新影響因子&#xff08;IF&#xff09; 2024年期刊最新影響因子&#xff08;IF&#xff09; BioinfoR生信筆記 &#xff0c;注于分享生物信息學相關知識和R語言繪圖教程。

java 設計模式_行為型_14策略模式

14.策略模式 策略模式作為一種軟件設計模式&#xff0c;指對象有某個行為&#xff0c;但是在不同的場景中&#xff0c;該行為有不同的實現算法。 策略模式把這些算法&#xff0c;都抽取出來&#xff0c;組成一個一個的類&#xff0c;可以任意的替換&#xff0c;大大降低了代碼…

【AI Study】第四天,Pandas(9)- 進階主題

文章概要 本文詳細介紹 Pandas 的進階主題&#xff0c;包括&#xff1a; 自定義函數高級索引數據導出實際應用示例 自定義函數 函數應用 # 基本函數應用 def calculate_bonus(salary, performance):"""計算獎金Args:salary (float): 基本工資performance (…

Boost dlib opencv vs2022 C++ 源碼安裝集成配置

?在進行人臉檢測開發時候出現 E1696: 無法打開源文件 "dlib/image_processing/frontal_face_detector.h 解決方案 1, 下載boost 需要:https://www.boost.org/ 或github git clone --recursive https://gitee.com/luozhonghua/boost.git 記住一定要完整版源碼…

rest_framework permission_classes 無效的解決方法

寫了一個特別簡單的view&#xff1a; csrf_exempt login_required() authentication_classes([TokenAuthentication]) permission_classes([IsAdminUser, IsAuthenticated]) def department_management_view(request):if request.method POST:department_name request.POST.…

Windows 體系對比 + 嵌入式開發全流程拆解

一、操作系統層級對比&#xff1a;Windows 家族 vs Linux 家族 角色Windows 體系Linux 體系本質核心內核Windows NT KernelLinux Kernel操作系統引擎&#xff08;管理CPU/內存/硬件&#xff09;完整操作系統Windows 11 Home/ProUbuntu / Debian / CentOS內核 界面 軟件 驅動…