【.NET Core 3.1】 策略授权中获取权限数据

更多精彩推荐,上午11点到达

随着项目关注度渐渐升高,目前已经1.2k个star,我的内心反而更加的惶恐了起来,最近也是很有强迫症,只要有小伙伴反馈项目的问题,就很着急,哪怕一丁点的问题,就需要思考很久,生怕是底层设计的问题,导致项目有不可挽回的后果,那就断送了整个项目的发展了。

不过目前还好吧,除了数据库连接偶尔有人反馈说,在异步并发中,会间歇性的出现连接关闭的问题,其他没有发现什么。当然如果感觉这个ORM不好用,换成EFCore也是一样的,其他的功能还是很抗的住,无论是DI、Filter、AOP还是授权。

但是就在前两天,我在优化代码的时候,为了做压测,把所有的附加功能都关了,当然缓存AOP也关闭了:


当时是没有考虑很多,就把代码提交到了远程Github,没想到引发了一次疑案,很凑巧,刚刚提交上去,立刻就有一个小伙伴反应了问题,说报错了,然后开了一个bug:


具体的错误场景是这样的,其他页面很正常,怎么刷新都没事儿,唯独【权限分配】页面报错了:


其实说实话,很久之前有人断断续续的问过这个小问题,但是我一直没有复现出来,所有就没办法去修改,这次正好有一个小伙伴遇到了,我当时一想,肯定是他自己修改了什么,导致出错了,我下载下来测试一下,就知道了。
没想到真的报错了,当时瞬间就感觉慌了,代码逻辑肯定是没有问题的,毕竟是写了一年了,也有很多人在使用,那这种幽灵问题是为何,如果一个项目出现幽灵bug,那是很纠心又难受的,所以,我决定让自己冷静冷静,好好的检测检测,故事就开始了。

今天不会去讲解什么是JWT,什么是授权,什么是自定义复杂策略授权,这些基本概念,可以看我的视频或者文章,今天主要说说,在复杂策略授权中,遇到的小问题。

01

到底是哪里的问题?

我看了一下错误报告,是这样的:

大概意思就是,通过sqlsugar请求的时候,因为我是策略授权,所以在PermissionHandler中,增加动态从数据库获取角色和接口的映射关系,所以现在在请求的时候,报错reader已经关闭了,不能再重复访问了,我当时一脸蒙圈。不会是Sqlsugar有问题吧,这要是底层的问题,可就难受了。看着情况应该是重复使用实例对象了,但是我service层用的是autofac注入没有问题呀,而且也是scoped的。

现在是找到了问题所在,就是我们的策略授权中,使用了

await _roleModulePermissionServices.RoleModuleMaps();

来获取角色菜单关系的缘故,下边我们就是根据问题来找方案了。

02

如何解决这个问题?

当时我就思考着,为何之前没有遇到过,是因为之前我用的是AOP缓存,这样每次请求,其实请求的是缓存的数据,所以不会出现重复使用数据库的DataReader,那方案以就出现了,我也是建议小伙伴这么弄的:

这样确实没有问题了,毕竟第一次是请求,后边十分钟都是在调用的缓存数据,肯定不会出现重复使用,但是这么说,心里没有底气呀,感觉自己都不好意思看到这个答案,夜里久久不能寐,继续研究。

夜里突然想起来一个问题,既然出现了问题,就要从问题根本着手处理,到底为什么会重复调用同一个DataReader?那肯定有一个地方用单例了,但是我的Service层就是Scope呀,继续研究,发现了问题所在。

我虽然Service是Scope的,但是授权处理器PermissionHandler当时图省事儿,设置了单例!


所以,这也就是导致了我们的Service是同一个实例了,而且很凑巧的是,Admin项目中的【权限分配】页里,正好同时发起了两次请求,就报错了。

解决方案就是把PermissionHandler的单例注入,改成Scoped注入即可:

03

进一步深入优化。

上边的改好了以后,我就深入的想了想,在PermissionHandler处理程序中,既然要获取全部的用户菜单关系,而且还是单例的,那为啥每次都要请求一次呢?登录的时候,获取一次不就行了?

var data = await _roleModulePermissionServices.RoleModuleMaps();

我们删除PermissionHandler中的相关代码,把他们移动到了登录页,获取token的时候:

 var user = await _sysUserInfoServices.Query(d => d.uLoginName == name && d.uLoginPWD == pass);if (user.Count > 0){var userRoles = await _sysUserInfoServices.GetUserRoleNameStr(name, pass);//如果是基于用户的授权策略,这里要添加用户;如果是基于角色的授权策略,这里要添加角色var claims = new List<Claim> {new Claim(ClaimTypes.Name, name),new Claim(JwtRegisteredClaimNames.Jti, user.FirstOrDefault().uID.ToString()),new Claim(ClaimTypes.Expiration, DateTime.Now.AddSeconds(_requirement.Expiration.TotalSeconds).ToString()) };claims.AddRange(userRoles.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));// 就是这里!!!var data = await _roleModulePermissionServices.RoleModuleMaps();var list = (from item in datawhere item.IsDeleted == falseorderby item.Idselect new PermissionItem{Url = item.Module?.LinkUrl,Role = item.Role?.Name,}).ToList();_requirement.Permissions = list;var token = JwtToken.BuildJwtToken(claims.ToArray(), _requirement);return new JsonResult(token);}

这样的话,我们登录的时候,更新一次,然后其他的时候,就不重复获取了,但是这样有个小小的问题,就是如果token有效,管理员在后端修改相应的菜单权限的话,就必须重新登录了,但是也无伤大雅,我已经在代码中注释。

那这样的话,我们就不用把PermissionHandler的依赖注入方式改成Scope了,这样也会每次都实例化,干脆还是改成单例,毕竟我们不用在授权处理程序中获取角色菜单关系了。

所以最后我的两个方案是:

1、在LoginController的登录api中,获取

_roleModulePermissionServices.RoleModuleMaps();

同时,注入的方式,改成Singleton;

2、还是在PermissionHandler中获取角色菜单Map,但是注入的方式一定要是Scope的。

04

打完收工

目前更新已经一天了,没有发现问题,有一个bug解决了。




????点击【阅读原文】查看Blog.Core开源项目地址

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

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

相关文章

sklearn决策树概述

决策树是一类常见的机器学习方法&#xff0c;决策树学习的目的是为了产生一棵泛化能力强&#xff0c;即处理未见示例能力强的决策树。决策树是个递归生成的过程&#xff0c;如何选择最优划分属性是决策树学习的关键。我们希望决策树的分支节点所包含的样本尽可能属于同一类别&a…

使用ASP.NET Core 3.x 构建 RESTful API - 3.4 内容协商

现在&#xff0c;当谈论起 RESTful Web API 的时候&#xff0c;人们总会想到 JSON。但是实际上&#xff0c;JSON 和 RESTful API 没有半毛钱关系&#xff0c;只不过 JSON 恰好是RESTful API 结果的表述格式。也就是说 RESTful API 还可以使用其它的表述格式&#xff0c;例如 xm…

sklearn随机森林概述

随机森林是一个拓展变体&#xff0c;在以决策树为基学习器构建Bagging集成的基础上&#xff0c;进一步在决策树的训练过程中引入了随机属性选择。具体来说&#xff0c;传统决策树在选择划分属性时是在当前结点的属性集合中选择一个最优属性&#xff1b;而在随机森林的每个结点&…

《Dotnet9》系列-开源C# Winform控件库1《HZHControls》强力推荐

大家好&#xff0c;我是Dotnet9小编&#xff0c;一个从事dotnet开发8年的程序员。我最近在写dotnet分享文章&#xff0c;希望能让更多人看到dotnet的发展&#xff0c;了解更多dotnet技术&#xff0c;帮助dotnet程序员应用dotnet技术更好的运用于工作和学习中去。文章阅读导航一…

sklearn集成学习概述

常见的集成学习有Voting、Bagging、Boost和Stacking。 Voting代码 from sklearn.model_selection import train_test_split from sklearn.datasets import make_moons from sklearn.ensemble import RandomForestClassifier from sklearn.ensemble import VotingClassifier f…

不要叫我,我会叫你

之前看过前辈Artech关于控制反转的一篇文章&#xff0c;文章通俗易懂且言语精炼&#xff0c;写技术文章既是积累也是分享&#xff0c;既然是分享那么必须让读者能够明白到底讲解的什么&#xff0c;所以在这里我也挑战下自己&#xff0c;看看能不能将概念通过简洁代码和语言的形…

用.NET模拟天体运动

用.NET模拟天体运动这将是一篇罕见而偏极客的文章。我上大学时就见过一些模拟太阳系等天体运动的软件和网站&#xff0c;觉得非常酷炫&#xff0c;比如这个&#xff08;http://www.astronoo.com/en/articles/positions-of-the-planets.html&#xff09;&#xff1a; 其酷炫之处…

01 手把手带你构建大规模分布式服务--高并发、高可用架构系列,高质量原创好文!...

作者&#xff1a;丁浪&#xff0c;目前在创业公司担任高级技术架构师。曾就职于阿里巴巴大文娱和蚂蚁金服。具有丰富的稳定性保障&#xff0c;全链路性能优化的经验。架构师社区特邀嘉宾&#xff01;阅读本&#xff08;系列&#xff09;文章&#xff0c;你将会收获&#xff1a;…

如何正确的探索 Microsoft Ignite The Tour

Microsoft Ignite The Tour 是一年一度微软为全球开发者、IT专家、安全专家以及数据专家提供的为期两天&#xff0c;包含众多核心产品的实践性技术培训。2019.12.10-2019.12.11 已经在北京国家会议中心胜利闭幕&#xff0c;我作为一名Speaker 参与了两门课程的分享&#xff0c;…

Leetcode贪心 种花问题

You have a long flowerbed in which some of the plots are planted, and some are not. However, flowers cannot be planted in adjacent plots. Given an integer array flowerbed containing 0’s and 1’s, where 0 means empty and 1 means not empty, and an integer n…

回顾这一年,我沉默良久

今天是一个特殊的日子&#xff0c;因为还有一周就2024了。 回忆 我骑着我心爱的小电驴慢悠悠的走在下班的路上&#xff0c;看着万家灯火&#xff0c;匆匆而过的行人和那开着三轮车的摊贩们与城管斗智斗勇。 我陷入了回忆&#xff1f; 回忆着今年的进程&#xff0c;先是裁员…

Cookie、session、token对比

Cookiecookie 是一个非常具体的东西&#xff0c;指的就是浏览器里面能永久存储的一种数据&#xff0c;仅仅是浏览器实现的一种数据存储功能。cookie由服务器生成&#xff0c;发送给浏览器&#xff0c;浏览器把cookie以kv形式保存到某个目录下的文本文件内&#xff0c;下一次请求…

Leetcode贪心 验证回文字符串

Given a string s, return true if the s can be palindrome after deleting at most one character from it. 思路 用头尾指针遍历原字符串&#xff0c;但碰到所指不相同时&#xff0c;需要退出循环记录此书指针的位置。分别去除两个指针上的内容&#xff0c;查看删除一个字符…

使用ASP.NET Core 3.x 构建 RESTful API - 4.1 面向外部的Model

Entity Framework Core 使用的 Entity Model 是用来表示数据库里面的记录的。 而面向外部的 model 则表示了要传输的东西。这类 model 有时候叫做 Dto&#xff0c;有时候叫做 ViewModel。 举一个例子&#xff0c;人员的Entity Model如下&#xff1a; 最后一个字段表示人员的出生…

特意向大家推荐.NET技术圈一些优秀开发者的公众号

在互联网技术飞速发展的今天&#xff0c;各种技术席卷而来&#xff0c;总是让人感觉压力山大。作为.NET开发者&#xff0c;我们该如何刷新自己&#xff0c;实现价值的提升呢&#xff1f;2019年.NET中国开发者峰会之后&#xff0c;我们汇总了.NET技术圈一些优秀开发者的公众号&a…

ASP.NET Core on K8S深入学习(11)K8S网络知多少

Photo &#xff1a;Kubernetes文 | Edison Zhou本文已加入《.NET Core on K8S 学习与实践系列文章索引目录》&#xff0c;点击查看阅读更多容器化相关文章&#xff0c;希望对你有所帮助&#xff01;Kubernetes网络模型我们都知道Kubernetes作为容器编排引擎&#xff0c;它有一个…

Leetcode动态规划 不同路径

A robot is located at the top-left corner of a m x n grid (marked ‘Start’ in the diagram below). The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked ‘Finish’ in the…

Amazon、Linux基金会开发边缘网络交换器操作系统

Amazon、Linux基金会和5家网络业者上周宣布边缘网络交换器操作系统项目DENT&#xff0c;可能冲击开发专属操作系统的网络晶片及设备业者。DENT希望集结网络设备制造商&#xff0c;系统整合商及晶片厂商&#xff0c;为分散式厂区、远端办公室、分公司及零售业开发解构式网络交换…

fit、transform与fit_transform

fit(x) 是对x进行训练 transform(y) 是将模型直接应用于y fit_transform(x) 是对x进行训练后再将模型应用于x x_test加fit&#xff0c;pca x_test不加fit -4 1 0.8855240762093011 0.6501925545571245 0.7678583153832128 -4 3 0.8855236186606635 0.6508344030808729 0.76817…

多库操作:多个数据库的动态切换(一)

▼更多精彩推荐&#xff0c;上午11点到达▼在平时的开发中&#xff0c;受到传统模式的影响&#xff0c;我们都是习惯了单一的数据库表操作&#xff0c;把数据都建到一个库里边&#xff0c;然后进行增删改查&#xff0c;这个是很经典的开发模式。但是随着项目开发&#xff0c;总…