21. 【.NET 8 实战--孢子记账--从单体到微服务】--简易权限--补充--自动添加角色可访问接口

上一篇文章我们一起编写了自动添加接口地址,这一篇文章我们补充简易权限中的自动添加角色可访问接口。

一 实现

首先,我们Initialization文件夹下新建AddRolePath类,这个类用于初始化数据库中SysRoleUrl表,代码如下:

using System.Reflection;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using SporeAccounting.Controllers;
using SporeAccounting.Models;
using SporeAccounting.Server.Interface;namespace SporeAccounting.Initialization;/// <summary>
/// 添加角色路径
/// </summary>
public static class AddRolePath
{/// <summary>/// 初始化/// </summary>/// <param name="serviceProvider"></param>public static void Init(IServiceProvider serviceProvider){using (var scope = serviceProvider.CreateScope()){var sysRoleUrlService = scope.ServiceProvider.GetService<ISysRoleUrlServer>();//1. 获取所有的URLvar sysUrlServer = scope.ServiceProvider.GetService<ISysUrlServer>();var urls = sysUrlServer?.Query();//2. 获取所有的角色var roleService = scope.ServiceProvider.GetService<ISysRoleServer>();var roles = roleService.Query();//3. 解析每个Controller的Authorize特性中Roles的角色var controllerRoles = new Dictionary<string, List<string>>();foreach (var controller in Assembly.GetExecutingAssembly().GetTypes().Where(t => typeof(ControllerBase).IsAssignableFrom(t))){var authorizeAttributes = controller.GetCustomAttributes<AuthorizeAttribute>();foreach (var attribute in authorizeAttributes){var controllerName = controller.Name.Replace("Controller", "");if (!controllerRoles.ContainsKey(controllerName)){controllerRoles[controllerName] = new List<string>();}controllerRoles[controllerName].AddRange(attribute.Roles.Split(','));}}List<SysRoleUrl> sysRoleUrls = new List<SysRoleUrl>();//4. 解析每个Controller的Action的特性如果有AllowAnonymous则跳过,反之拼接Controller和Action生产接口地址foreach (var controller in Assembly.GetExecutingAssembly().GetTypes().Where(type => typeof(BaseController).IsAssignableFrom(type))){var actions = controller.GetMethods().Where(m => m.IsPublic && !m.GetCustomAttributes<NonActionAttribute>().Any());foreach (var action in actions){if (action.GetCustomAttributes<AllowAnonymousAttribute>().Any()){continue;}var routeAttribute = controller.GetCustomAttribute<RouteAttribute>();var actionRouteAttribute = action.GetCustomAttribute<RouteAttribute>();if (routeAttribute == null || actionRouteAttribute == null){continue;}var controllerRoute = routeAttribute.Template;var controllerName = controller.Name.Replace("Controller", "");if (controllerRoute.Contains("[controller]")){controllerRoute =controllerRoute.Replace("[controller]", controllerName);}var actionName = actionRouteAttribute.Template;if (actionName.Contains("[action]")){actionName = actionName.Replace("[action]", action.Name);}actionName = actionName.Split("/")[0];var route = $"/{controllerRoute}/{actionName}".Replace("//", "/");controller.Name.Replace("Controller", "");foreach (var kv in controllerRoles){if (kv.Key == controllerName){foreach (var role in kv.Value){var roleId = roles?.FirstOrDefault(x => x.RoleName == role)?.Id;var urlId = urls?.FirstOrDefault(x => x.Url == route)?.Id;bool isExist = sysRoleUrlService.IsExist(roleId, urlId);if(isExist){continue;}SysRoleUrl sysRoleUrl = new SysRoleUrl(){UrlId = urlId,RoleId = roleId,CreateUserId = "b47637e2-603f-4df0-abe9-88d70fa870ee"};sysRoleUrls.Add(sysRoleUrl);}}}}}//5. 将角色id和urlid添加到SysRoleUrl表中sysRoleUrlService.Add(sysRoleUrls);}}
}

这段代码实现了动态为系统中的角色分配 API 路径的功能。通过反射获取当前程序集的所有控制器及其方法,解析其特性并提取路径和角色信息,然后将这些信息与数据库中的已有角色和路径数据进行匹配,生成角色与路径的映射,并最终存储到数据库表中。代码的入口是静态类 AddRolePathInit 方法,它接受一个 IServiceProvider 参数,用于获取依赖服务。首先,代码通过创建依赖注入的作用域,获取 ISysRoleUrlServerISysUrlServerISysRoleServer 三个服务实例,分别用于管理角色与路径的关联、查询系统路径和查询角色数据。然后,代码调用相关方法查询所有路径和角色的信息,为后续操作提供基础数据。
接着,通过反射机制遍历当前程序集中的所有控制器类型,筛选出继承自 ControllerBase 的类型,并提取其 AuthorizeAttribute 特性中的 Roles 信息,记录在一个字典中,字典的键是控制器的名称(去除 “Controller” 后缀),值是控制器对应的角色列表。随后,代码进一步解析控制器中每个公开方法的路径信息,方法路径通过读取控制器和方法的 RouteAttribute 特性来拼接而成,同时会跳过带有 AllowAnonymous 特性的方法,以确保仅处理需要授权的路径。解析出的路径与控制器角色信息进行匹配,生成角色和路径的映射。
在生成角色与路径的映射关系时,代码会通过调用 sysRoleUrlService.IsExist 检查映射是否已经存在,以避免重复插入。对于不存在的映射,创建新的 SysRoleUrl 实例,设置其 RoleIdUrlIdCreateUserId 属性,并将其添加到集合中。最后,调用 sysRoleUrlService.Add 方法,将所有新的映射批量写入数据库,从而完成初始化操作。这段代码的实现提供了一种动态、自动化的方式管理角色和 API 路径的关联,既减少了手动配置的繁琐,又提升了系统的灵活性和可维护性。

二、总结

本文通过 AddRolePath 类实现了动态分配角色与接口路径的功能。代码利用反射获取控制器及其方法,解析 AuthorizeRoute 特性,提取路径和角色信息,生成映射关系并存储到数据库中。此方法减少了手动配置的繁琐,提高了权限管理的自动化和灵活性,为系统提供了高效的权限初始化方案。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/891211.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

标准库以及HAL库——按键控制LED灯代码

按键控制LED本质还是控制GPIO,和点亮一个LED灯没什么区别 点亮一个LED灯&#xff1a;是直接控制输出引脚&#xff0c;GPIO初始化推挽输出即可 按键控制LED&#xff1a;是按键输入信号从而控制输出引脚&#xff0c;GPIO初始化推挽输出一个引脚以外还得加一个GPIO上拉输入 但是…

关于Camunda工作流的使用后的记录

服务器机器2台&#xff0c;8u32G 服务器负载长期极低,近30日监控数据&#xff0c;CPU 1分钟负载高峰时不到0.2 数据库机器单台&#xff0c;4u16G 数据库总连接数&#xff1a;最大值47&#xff0c;最小值16 CPU使用率&#xff1a;最大值25.7%&#xff0c;最小值6% IOPS(单位时间…

Java的list中状态属性相同返回true的实现方案

文章目录 项目背景方案一、for循环实现实现思路 方案二、stream实现实现思路 项目背景 在项目中会遇到list中多个状态判断&#xff0c;状态值相等时&#xff0c;总体返回为true。 方案一、for循环实现 实现思路 遍历list&#xff0c;当出现不一致时&#xff0c;直接跳出循环…

模型选择+过拟合欠拟合

训练误差和泛化误差 训练误差&#xff1a;模型在训练数据上的误差 泛化误差&#xff1a;模型在新数据上的误差 验证数据集&#xff1a;一个用来评估模型好坏的数据集 例如拿出50%的数据作为训练 测试数据集&#xff1a;只能用一次 K则交叉验证 在没有足够数据时使用 算法…

Web安全攻防入门教程——hvv行动详解

Web安全攻防入门教程 Web安全攻防是指在Web应用程序的开发、部署和运行过程中&#xff0c;保护Web应用免受攻击和恶意行为的技术与策略。这个领域不仅涉及防御措施的实现&#xff0c;还包括通过渗透测试、漏洞挖掘和模拟攻击来识别潜在的安全问题。 本教程将带你入门Web安全攻防…

Qt仿音乐播放器:QFileDialog添加本地文件

一、套路 QFileDialog fileDialog(this);// 创建对话框&#xff0c;并设置父元素&#xff1b;fileDialog.setWindowTitle("添加本地下载的音乐");//设置窗口标题//设置文件对话框的默认打开路径 QString projectPathQDir::currentPath();//获取当前目录 QDir dir(pr…

语音识别基础算法——动态时间规整算法

前言 动态时间规整算法&#xff0c;Dynamic Time Wraping&#xff0c;缩写为DTW&#xff0c;是语音识别领域的一个基础算法。 算法的提出 DTW 的提出是为了解决或尽量解决在语音识别当中的孤立词识别不正确的问题。该问题简单描述为&#xff1a;在识别阶段&#xff0c;将输入…

SAP SD信贷管理信用管理手册(下)

1、项目类别的信贷激活 图1-12-1.项目类别的信贷设置路径 图1-12-2.项目类别的信贷参数激活 说明&#xff1a;项目类别是否进行信贷管理设置。 2、定义信贷组 图1-13-1.定义信贷组路径 图1-13-2.信贷组定义 说明&#xff1a;信贷组参与后续信贷控制的组合分配。 3、销售凭证及…

分布式项目___某污水处理项目

一.分布式项目___污水处理项目 项目地址:https://gitee.com/yanyigege/collaborative-water-springboot.git ​ 1.项目背景 总公司在全国各地有处理污水的项目部,各项目部处理自己的污水,总部需要监控各地分项目部每天处理污水的原料用量,掌握各分部的污水处理情况 ​ 2.功…

网页排名:PageRank 算法的前世今生

PageRank算法全解析&#xff1a;从理论到实践 引言 PageRank 是由拉里佩奇&#xff08;Larry Page&#xff09;和谢尔盖布林&#xff08;Sergey Brin&#xff09;在1996年发明的一种链接分析算法&#xff0c;最初用于Google搜索引擎来评估网页的重要性。该算法通过模拟随机浏览…

Nginx详细安装配置过程

目录 1.nginx环境准备 1.1 在配置好yum源之后&#xff0c;安装如下的编译工具 1.2 安装nginx所需的依赖库 1.3 关闭防火墙&#xff0c;selinux&#xff0c;并确保网络正常 2.nginx的编译安装 2.1从nginx官网复制下载链接&#xff0c;wget 下载 2.2? 解压nginx源代码 2…

滴滴数据分析80道面试题及参考答案

如何衡量分类好坏? 衡量分类好坏有多种方法,常用的有准确率、精确率、召回率、F1 值、ROC 曲线与 AUC 值等。 准确率:是指分类正确的样本数占总样本数的比例,计算公式为:准确率 = (分类正确的样本数)/(总样本数)。准确率越高,说明分类器整体的分类效果越好,但在正负…

C语言内存管理函数

面试里会遇到让自己编写一个内存管理函数 1. memset 将指定的内存区域的每个字节设置为指定的值 函数原型: void *memset(void *s, int c, size_t n); 参数: s: 指向要填充的内存块的指针。c: 要设置的值&#xff08;会被转换为无符号字符&#xff09;。n: 要设置的字节数。…

2025年阿里云认证改版新消息!2025年阿里云认证考试内容有变!

阿里云认证已经确定在2025年要进行大改&#xff0c;这次改动幅度会比2023年改动更大&#xff0c;2023年主要改变是在考试题型上的变化&#xff0c;这次则主要是考试内容的变化了&#xff01; 2023年阿里云ACP认证考试的改版变化主要有&#xff1a; &#xff08;一&#xff09…

【Scala】图书项目系统代码演练3.1/BookService

package org.app package serviceimport models.{BookModel, BorrowRecordModel}import org.app.dao.{BookDAO, BorrowRecordDAO}import java.time.LocalDateTime import scala.collection.mutable.ListBuffer// 图书业务逻辑层 class BookService {private val bookDAO new B…

面试题 2024-12-30

1. 鸿蒙系统中的 WebSocket 心跳协议 原理&#xff1a;在鸿蒙应用开发里&#xff0c;WebSocket 心跳协议的底层逻辑和通用的 WebSocket 心跳一致。由于鸿蒙系统也会运行在各类智能设备上&#xff0c;网络环境复杂多变&#xff0c;为维持长连接&#xff0c;客户端与服务器需定时…

Ajax数据爬取

有时我们用requests 抓取页面得到的结果&#xff0c;可能和在浏览器中看到的不一样:在浏览器中可以看到正常显示的页面数据&#xff0c;而使用requests 得到的结果中并没有这些数据。这是因为 requests 获取的都是原始 HTML 文档&#xff0c;而浏览器中的页面是JavaScript 处理…

回顾python3中的字典

一. 简介 前面文章学习了python3中字典的一些操作。本文来回顾一下 python3中字典。主要包括字典的创建&#xff0c;访问字典中键值对&#xff0c;更改或删除字典中元素。 二. 回顾python3中的字典 字典是另一种可变的数据类型&#xff0c;且可存储任意类型对象。 1. 创建字…

SpringCloud整合skywalking实现链路追踪和日志采集

1.部署skywalking https://blog.csdn.net/qq_40942490/article/details/144701194 2.添加依赖 <!-- 日志采集 --><dependency><groupId>org.apache.skywalking</groupId><artifactId>apm-toolkit-logback-1.x</artifactId><version&g…

E卷-恢复数字序列(100分)

🔗 OD专栏订阅 恢复数字序列 问题描述 对于一个由连续正整数组成的序列,可以将其拼接成一个字符串,然后将字符串中的部分字符打乱顺序。例如,序列 8 9 10 11 12 拼接成的字符串为 89101112,打乱一部分字符后可能得到 90811211,其中原来的正整数 10 被拆成了 0 和 1。…