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上拉输入 但是…

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安全攻防…

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

前言 动态时间规整算法&#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.功…

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…

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…

Ajax数据爬取

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

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…

12.30 Redis网络模型基础 IO NIO多路复用

图片引用自黑马程序员redis 网络模型 上图引用自java guide javaguide NIO

【智行安全】基于Synaptics SL1680的AI疲劳驾驶检测方案

随著车载技术的快速进步&#xff0c;驾驶安全越来越受到重视&#xff0c;而疲劳驾驶是造成交通事故的重要原因之一。传统的驾驶监控技术因精度不足或反应迟缓&#xff0c;无法满足实时监测需求。因此&#xff0c;结合人工智能技术的疲劳驾驶检测系统成为行业新方向&#xff0c;…

手机实时提取SIM卡打电话的信令声音-智能拨号器的SIP线路-双卡双待单通方案

手机实时提取SIM卡打电话的信令声音 --智能拨号器的SIP线路-双卡双待单通方案 一、前言 蓝牙电话的技术方案最初是从蓝牙耳机和车机蓝牙的使用领域延伸出来的技术方式。通过蓝牙的HFP协议&#xff0c;把手机通话的声音和通话事件状态提取出来进行复用和处理。但中国大陆现行…

HTML——26.像素单位

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>像素</title></head><body><!--像素&#xff1a;1.指设备屏幕上的一个点&#xff0c;单位px&#xff0c;如led屏上的小灯朱2.当屏幕分辨率固定时&…

LeetCode:513.找二叉树左下角的

跟着carl学算法&#xff0c;本系列博客仅做个人记录&#xff0c;建议大家都去看carl本人的博客&#xff0c;写的真的很好的&#xff01; 代码随想录 LeetCode&#xff1a;513.找二叉树左下角的 给定一个二叉树的 根节点 root&#xff0c;请找出该二叉树的 最底层 最左边 节点的…

如何使用 ChatGPT Prompts 写学术论文?

第 1 部分:学术写作之旅:使用 ChatGPT Prompts 进行学术写作的结构化指南 踏上学术写作过程的结构化旅程,每个 ChatGPT 提示都旨在解决特定方面,确保对您的主题进行全面探索。 制定研究问题: “制定一个关于量子计算的社会影响的研究问题,确保清晰并与您的研究目标保持一…

Mcnemar‘s exact test

与卡方检验的区别 与fisher exact test区别

全面Kafka监控方案:从配置到指标

文章目录 1.1.监控配置1.2.监控工具1.3.性能指标系统相关指标GC相关指标JVM相关指标Topic相关指标Broker相关指标 1.4.性能指标说明1.5.重要指标说明 1.1.监控配置 开启JMX服务端口&#xff1a;kafka基本分为broker、producer、consumer三个子项&#xff0c;每一项的启动都需要…