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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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内核 界面 软件 驱动…