吐槽一下Abp的用户和租户管理模块

1. 背景

ASP.NET Core 基于声明的访问控制到底是什么鬼?

聊到基于声明的身份认证将 身份和签发机构分离,应用程序信任签发机构,故认可签发的身份信息。

-----------
ClaimB站:438962688
Name:饭思思_
weibo:538210234
Name:饭思思van
姓名:不详
籍贯:九江
ClaimsIdentity哔哩哔哩账户微博账户身份证
ClaimsPrincipal


于是我们通常会有如下:

 var claims = new[] {new Claim(nameof(ClaimTypes.NameIdentifier),_authData.Data["userId"].ToString(),ClaimValueTypes.String),new Claim(nameof(ClaimTypes.Name),_authData.Data["userName"].ToString(),ClaimValueTypes.String),new Claim("profileId",_authData.Data["profileId"].ToString()),new Claim("positionId",_authData.Data["positionId"].ToString()),new Claim("organizationId",_authData.Data["organizationId"].ToString()),new Claim("maxAge",_authData.Data["maxAge"].ToString()),};// 设置身份卡片内容 、身份卡片核心Name, 这个时候HttpContext.Uservar identity = new ClaimsIdentity(claims, Scheme.Name,nameof(ClaimTypes.Name),nameof(ClaimTypes.Role));Context.User = new ClaimsPrincipal(identity);

我们现在可以在Action中使用 HttpContext.User.Identity 获取声明的身份信息。

当我满心欢喜在Abp vnext中封装的ICurrentUser接口获取身份信息,却无法获取身份信息。

ICurrentUser 封装了身份信息,用于获取有关当前活动的用户信息,已经被Abp框架默认注入。
你会在ApplicationSerive、 AbpController看到属性CurrentUser, 在Abp服务和控制器中是可以即时使用的。

------


2. Abp用户、租户管理

AbpICurrentUser获取不到常规HttpContext.User信息,是因为使用了特定的封装,封装的方式我不能苟同:

以下是 ICurrentUser 接口的基本属性:IsAuthenticated 如果当前用户已登录(已认证),则返回 true. 如果用户尚未登录,则 Id 和 UserName 将返回 null.
Id (Guid?): 当前用户的Id,如果用户未登录,返回 null.
UserName (string): 当前用户的用户名称. 如果用户未登录,返回 null.
TenantId (Guid?): 当前用户的租户Id. 对于多租户 应用程序很有用. 如果当前用户未分配给租户,返回 null.
Email (string): 当前用户的电子邮件地址. 如果当前用户尚未登录或未设置电子邮件地址,返回 null.
Roles (string[]): 当前用户的角色. 返回当前用户角色名称的字符串数组.
.....

这里面有几个问题:

①    ICurrentUser将用户id、租户TenantId硬编码为GUID
项目原始的身份id、租户id若不为GUID,则根本不可用。
最差的情况也应该用个泛型,由应用决定特定身份片段的类型。

②      ICurrentUser 修改了IsAuthenticated的取值逻辑

  • ASP.NET Core官方认证类型不为空,就认为用户认证通过。

   // --- 来自asp.netcore源码:https://github.com/dotnet/runtime/blob/master/src/libraries/System.Security.Claims/src/System/Security/Claims/ClaimsIdentity.cspublic virtual bool IsAuthenticated{get { return !string.IsNullOrEmpty(_authenticationType); }}.....
  • Abp官方则认为UserId不为空,就认为用户认证通过。

   // ---截取自abp官方源码:Volo.Abp.Users.CurrentUserpublic class CurrentUser : ICurrentUser, ITransientDependency{private static readonly Claim[] EmptyClaimsArray = new Claim[0];public virtual bool IsAuthenticated => Id.HasValue;.....}

 ③  ICurrentUser修改了UserName的取值逻辑

  • Asp.NetCore检索声明信息中ClaimType==某个NameClaimType的Claim值, 作为身份认证卡片Identity的Name, 更灵活

  • Abp 检索声明信息中ClaimType=="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"的值,作为身份验证卡片的Name, 硬编码

Abp 将UserId、TenantId 硬编码为GUID,已经不够通用;  

另外Abp强行变更了ASP.NET Core基于声明的身份验证的取值逻辑,若要我们接受,需要一点学习成本。

本次我的项目就是因为UserID、TenantId为String,  在Abp CurrentUser中转换失败;Name也取值失败。  

在项目中就无法愉快地使用Abp ApplicationService、AbpController的CurrentUser属性。

3. 针对Abp用户、租户管理的应对方法

我的策略:还是向尽量使用Abp框架,尽量做到【对修改封闭,对扩展开放】,

于是我仿照Abp的CurrentUser实现了适合自身项目的CurrentUser:

public class CurrentUser: ITransientDependency
{private static readonly Claim[] EmptyClaimsArray = new Claim[0];public virtual string  Id => _principalAccessor.Principal?.Claims?.FirstOrDefault(c => c.Type == nameof(ClaimTypes.NameIdentifier))?.Value;public virtual string UserName => _principalAccessor.Principal?.Claims?.FirstOrDefault(c => c.Type == nameof(ClaimTypes.Name))?.Value;public virtual string Email => _principalAccessor.Principal?.Claims?.FirstOrDefault(c => c.Type == nameof(ClaimTypes.Email))?.Value;public virtual string TenantId => _principalAccessor.Principal?.Claims?.FirstOrDefault(c => c.Type == "profileId")?.Value;public virtual string[] Roles => FindClaims("roleId").Select(c => c.Value).ToArray();private readonly ICurrentPrincipalAccessor _principalAccessor;public CurrentUser(ICurrentPrincipalAccessor principalAccessor){_principalAccessor = principalAccessor;}public virtual Claim FindClaim(string claimType){return _principalAccessor.Principal?.Claims.FirstOrDefault(c => c.Type == claimType);}
}

编写继承自ApplicationService、AbpController的通用服务类、控制器类:

new关键字显式隐藏从基类继承的成员

这样我们既可以使用 Abp框架其他能力,利用new关键词我们也刻意覆盖了框架原有的ICurrentUser属性,

其他同事也不需要额外的认知成本就可以开心地像往常一样使用CurrentUser属性。


  • 学完这篇依赖注入,与面试官扯皮就没有问题了。

  • 我又踩坑了!如何为HttpClient请求设置Content-Type标头?

  • 临近年关,修复ASP.NET Core因浏览器内核版本引发的单点登录故障

  • 手撕公司SSO登录原理

  • 实战解读ASP.NET Core身份认证

  • ASP.NET Core应用注意这一点,CTO会对你刮目相看

- END -

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

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

相关文章

后端学习 - JDBC

文章目录一 JDBC概述1 Java中的数据存储技术2 什么是JDBC3 JDBC程序的编写步骤二 Java连接数据库的方式三 使用 PreparedStatement 实现 CRUD 操作1 数据库的调用的三个接口2 增Create/删Delete/改Update 操作3 查Retrieval操作4 批量插入操作四 数据库事务1 事务2 事务的 ACID…

.NET架构小技巧(3)——反射,架构人员法宝I

如题,这是我的心声,反射在我的开发中用的频次还是比较高的,有一本万利的感觉,一段复杂的代码,可以节省大量的时间;但带来的一个问题性能相对较差,所以要选择适合的场景使用。关于C#中的反射基本…

米家扫地机器人充满电需要多长时间_米家扫地机器人充满电后能工作多久?

硬件及结构相关1、Q:米家扫地机器人的激光对小孩或宠物有伤害吗?A:米家扫地机器人通过了IEC 60825-1:2014激光安全等级Class 1的认证,不会对儿童或者宠物带来伤害请放心使用。2硬件及结构相关1、Q:米家扫地机器人的激光…

后端学习 - JavaWeb

技术体系 文章目录一 HTML1 网页的组成部分2 HTML 概述3 HTML 标签4 常用标签5 表单与表单的提交二 CSS1 语法格式2 使用方法三 JavaScript1 概述2 与 HTML 结合的两种方式3 变量类型及特殊值4 关系、逻辑运算5 数组6 函数7 事件8 DOM (Document Object Model&#…

python中的while语句怎么居中_python基础之while语句操作

# i 0# while (i < 9):# print("i ----> ",i)# i i 1# print(i,"i即将大于或者等于9,while不在执行")#执行1-100的数字# a1 1# while a1 < 100:# print(a1,end" ")# a1 a1 1#执行100 -1 的数字# a1 100# while a1 > 0:# prin…

心想技术驱动业务,却在背道而驰

这里是Z哥的个人公众号每周五11&#xff1a;45 按时送达当然了&#xff0c;也会时不时加个餐&#xff5e;我的第「165」篇原创敬上大家好&#xff0c;我是Z哥。相信每一位真正的程序员心里都有这样一个念想&#xff1a;只要我的技术够牛&#xff0c;就能驱动业务的发展。但是往…

后端学习 - SpringMVC

文章目录一 SpringMVC 简介1 MVC2 SpringMVC3 创建第一个 SpringMVC 项目二 RequestMapping1 注解类与方法的区别2 value 属性3 method 属性4 params 属性5 headers 属性6 SpringMVC 支持路径中的占位符三 获取 Request 的一系列参数1 通过控制器方法的形参2 控制器方法形参 映…

hbase shell远程连接_hbase与phoenix集成

Phoenix是构建在HBase之上的关系型数据库层&#xff0c;作为内嵌的客户端JDBC驱动用以对HBase中的数据进行低延迟访问Phoenix会将用户编写的sql查询编译为一系列的scan操作&#xff0c;最终产生通用的JDBC结果集返回给客户端Phoenix可以看成是mysql准备安装包apache-phoenix-4.…

对精致码农大佬的 [理解 volatile 关键字] 文章结论的思考和寻找真相

一&#xff1a;背景1. 讲故事昨天在园里的编辑头条看到 精致码农大佬 写的一篇题为&#xff1a;[C#.NET 拾遗补漏]10&#xff1a;理解 volatile 关键字 (https://www.cnblogs.com/willick/p/13889006.html) 的文章&#xff0c;大概就是说在 多线程环境下&#xff0c;一个在debu…

后端学习 - SpringBoot

SpringBoot 是整合 Spring 技术栈的一站式框架&#xff0c;是简化 Spring 技术栈的快速开发脚手架约定大于配置 文章目录一 概述1 第一个 SpringBoot 项目2 SpringBoot 特性&#xff1a;依赖管理3 SpringBoot 特性&#xff1a;自动配置二 SpringBoot 的 IOC容器1 组件添加&…

centos rpm 安装 perl_Linux【常用软件安装篇】

摘要&#xff1a;本文介绍Linux常用的软件安装方式以及jdk、vim、mysql、tomcat、redis的安装过程。1 Linux常用软件安装方式常用方式有&#xff1a;rmp包安装、yum指令安装、源码包安装、解压免安装。1.1 rpm包安装rpm是Red-Hat Package Manager&#xff08;RPM软件包管理器&a…

日计不足涓滴成河-自定义响应结果格式化器

什么是响应结果响应结果就是&#xff0c;在客户端向服务器发出请求后&#xff0c;服务器根据客户端的请求参数&#xff0c;给出的结果&#xff0c;这就是一个完整的响应结果过程。响应的结果包含的内容非常多&#xff0c;主要的有 HTTP Status Code&#xff0c;Content-Type,Co…

docker 容器启动顺序_Docker容器启动时初始化Mysql数据库

1. 前言 Docker在开发中使用的越来越多了&#xff0c;最近搞了一个Spring Boot应用&#xff0c;为了方便部署将Mysql也放在Docker中运行。那么怎么初始化 SQL脚本以及数据呢&#xff1f; 我这里有两个传统方案。 第一种方案是在容器启动后手动导入&#xff0c;太low了不行。第二…

后端学习 - JVM(上)内存与垃圾回收

JVM 架构图 文章目录一 JVM 简介二 类加载子系统&#xff1a;1 作用2 类的三个加载过程3 类加载器的分类4 双亲委派机制 & Tomcat为何不遵循5 两个 class 对象为同一个类的必要条件三 运行时数据区&#xff1a;PC寄存器&#xff08;Program Counter Register&#xff09;四…

SM2 国密算法被 Linux 内核社区接受

喜欢就关注我们吧&#xff01;10 月 25 日&#xff0c;有开发者发文称&#xff0c;SM2 国密算法终于被 Linux 内核社区接受了。该作者表示&#xff0c;SM2 的补丁已经更新到了 v7 版本&#xff0c;这个版本的补丁最终被社区接受&#xff0c;目前已经合并到了 Linux 主线的 5.10…

后端学习 - MyBatis

MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的 持久层框架 文章目录一 基于配置文件的 MyBatis 搭建1 搭建过程&#xff08;增删改&#xff09;2 查询操作3 特殊操作二 MyBatis 获取参数值的方式1 单个字面量类型的参数2 多个字面量类型的参数3 Map 类型的参数4 实体…

向下兼容性格什么意思_担心对方只是向下兼容,并不是从心底里接纳我怎么办?...

无需刻意累计帮助了44人题主你好&#xff0c;不知道什么时候“向下兼容”这个词被用在了人际关系上&#xff0c;只就我个人所了解的话&#xff0c;这是一个很不严谨的用法。因为在自我接纳中用了“向下”本身就意味着不平等和不接纳。形容一个人“向下兼容”本身就自带了否认倾…

国产操作系统发展离不开人才和市场

日前&#xff0c;中国 1024 程序员节盛大举行&#xff0c;一大批开源大咖齐聚千年岳麓&#xff0c;围绕开源标准、生态、人才发展等主题分享&#xff0c;共议开源软件与操作系统未来。其中&#xff0c;统信软件总经理刘闻欢表示&#xff0c;“有了市场才会被真正的用起来”&…

zynq网络时钟控制寄存器_ZYNQ笔记(6):普通自定义IP封装实现PL精准定时中断...

软件的定时中断很难控制精准触发沿的位置&#xff0c;可以通过 PL-PS 的中断完成精准的定时中断。PL 的中断通过 Verilog 代码产生&#xff0c;这样紧密结合 PS-PL 的处理&#xff0c;发挥各自的优势。一、PL 侧定时中断1.实际要求① 上升沿中断&#xff1b;② 高电平宽度不小于…

后端学习 - Redis

文章目录一 Redis 概述Redis 为什么是单线程&#xff0c;单线程为什么这么快&#xff1f;数据存储结构二 常用数据类型1 String2 HashHash 的扩容机制&#xff1a;渐进式 rehash*3 List4 Set5 Zset三 Redis 事务1 乐观锁与 watch 命令2 事务的三个特性四 Redis 持久化1 RDB(Red…