ASP.NET Core - 基于IHttpContextAccessor实现系统级别身份标识

问题引入:

  我们知道当请求通过认证模块时,会给当前的HttpContext赋予当前用户身份标识,我们在需要授权的控制器中打上[Authorize]授权标签,就可以在ControllerBase的User属性获取到基于声明的权限标识(ClaimsPrincipal)。遗憾的是这只是针对Controller层面,很多场景下我们是需要在Service层乃至数据层获直接使用用户信息,这种情况我们就使用不了User了。  


解决方案:

  在Asp.net 4.x时代,我们通常的做法是通过HttpContext.Current获取当前请求的上下文进而获取到当前的User属性,所以问题的切入点在于我们如何获取当前的HttpContext上下文,Aspnet Core是通过注入HttpContext的访问器对象IHttpContextAccessor来获取当前的HttpContext。

  首先我们需要在Startup的ConfigureServices方法中注册IHttpContextAccessor的实例

   有了这个注册,我们封装一个方法从IHttpContextAccessor 的HttpContext中获取对应的ClaimsPrincipal,如下(这里面的原理在后面的认证授权文章将会讲解到,大概的原理是认证通过后,User是具有当前用户的身份标志的ClaimsPrincipal):

640?wx_fmt=png

   在Startup的ConfigureServices方法中,我们一样把这个类也加入注册中

public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<IPrincipalAccessor, PrincipalAccessor>();
....
}

   有了以上这些基础架构提供的东西,剩下的是我们该需要如何从ClaimsPrincipal获取到对应的Claims了,在这里我们定义一个ClaimsAccessor类负责从PrincipalAccessor把用户的身份标志信息提取出来,比如用户的角色,Id等业务数据,这些是需要在获取Token时系统所提供过的信息。

 

640?wx_fmt=png

640?wx_fmt=png

   同样我们在Startup的ConfigureServices方法中把IClaimsAccessor注册进来

public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<IPrincipalAccessor, PrincipalAccessor>();
services.AddSingleton<IClaimsAccessor, ClaimsAccessor>();
....
}

  这样我们所涉及到的需获取身份标志的基础类都已经定义好,来看看我们该如何使用这些基础类。

  使用

  在有了以上的这些类,我们需要的是在业务中通过依赖注入方式来解析出我们所需的对象,来好的让我们看看该如何具体使用  

640?wx_fmt=png


  当我们的IClaimsAccessor解析出来时,我们就获取到所有的Claims信息,可以基于这些信息提取访问用户的身份标志,这样我们就不仅仅局限于在Controller层面才能获取用户的身份标志了,至此我们的系统级别的标识已经完成,记得在项目的启动项中利用ASP.NET Core的容器把服务注册进来,在需通的地方解析出来即可使用。

  改进

  这时能满足我们的业务吗?能!但是对于我们稍微要求高点的程序员,我们就可以发现,如果每个服务都按照上面的写法的话,明显在实际应用中需要写很多重复的代码,每次都需要手动进行构造注入会比较繁琐,好吧,我们可以利用面向对象的特点,创建基类进行继承进行优雅且可复用的简化和改进

  首先我们先定义一个ServiceProviderInstance类

  public class ServiceProviderInstance
{
public static IServiceProvider Instance { get; set; }
} 

  这个类的作用是保存IServiceProvider的一个实例,为什么需要这样呢?这里的一个设计思想是,我们如何能顺利解析出我们所需的IClaimsAccessor对象进而得到我们所需的信息?在ASP.NET Core的容器中,系统提供了IServiceCollection来注册服务和提供了IServiceProvider这个让我们解析各种注册过的服务(具体可参考ASP.NET Core - 依赖注入文章所讲解的依赖注入),这时我们的目标就是需要获取到当前应用的IServiceProvider实例,所以这个ServiceProviderInstance类的作用时为了获取IServiceProvider所设计出来的静态类。

  如何获取到应用的IServiceProvider实例?

  在应用初始化过程中,WebHostBuilder会利用ServiceCollection来创建新的ServiceProvider来供系统使用,所以我们在Startup类的Configure方法中,通过ApplicationBuilder的ApplicationServices属性就能获取到系统的ServiceProvider实例,在此我们利用ServiceProviderInstance的Instance属性保存当前的IServiceProvider以供系统后面使用  

  public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
...
ServiceProviderInstance.Instance = app.ApplicationServices;
}

  在获取到了系统的IServiceProvider实例后,剩下的就是利用这个实例把我们前面注册的基础服务IClaimsAccessor解析出来了

640?wx_fmt=png


   好的让我们看看改进后在一个实际环境中该如何使用

 

640?wx_fmt=png

  让所有每个子类都继承了ServiceBase,这样在所有的业务层都可以直接获取到用户的身份信息而不用写太多的重复代码。

  总结

  1. 利用ASP.NET Core提供的IHttpContextAccessor来获取HttpContext的User属性

  2. 封装一系列的基础类和利用依赖注入来解析出所有的Claims

  3. 为了避免过多的侵入式代码,优雅且可复用的创建ServiceBase给所有的业务类使用

  让我知道如果你有更好的想法或建议!

原文地址:https://www.cnblogs.com/lex-wu/p/10528109.html

.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com 
640?wx_fmt=jpeg

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

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

相关文章

怎样学习和阅读技术书籍?

技术的更新换代非常的迅速&#xff0c;作为一个技术人&#xff0c;需要持续不断地学习才能不被淘汰。但是学习没有速成的方法&#xff0c;只可能有一些技巧让我们事半功倍&#xff0c;本文是我对学习和读书的一点思考。学习是一件「逆人性」的事&#xff0c;如果让你选择是学习…

52ABP和ABP的关系

52ABP和ABP的关系本文作者&#xff1a;52ABP开发团队 文章会随着版本进行更新&#xff0c;关注我们获取最新版本 本文出处&#xff1a;https://www.52abp.com/wiki/common/latest 源代码&#xff1a; https://www.github.com/52abp 52ABP和ABP的关系ASP.NET Boilerplate是一个开…

【译】C#9的候选功能

通往C# 9 的漫长道路已经开始了&#xff0c;这是世界上第一篇关于C# 9候选功能的文章。阅读完本文后&#xff0c;你将希望为将来遇到新的C#挑战做好充分准备。 这篇文章基于&#xff1a;C#语言版本计划 9.0 候选功能基于记录和模式匹配的表达式我一直在长时间等待这个功能。记录…

AKS开讲啦! | DevOps with AKS

上周小Phippy搬到了Kube船长船上的Pods里&#xff0c;感觉好极了&#xff0c;那今天我们继续看看Phippy的兴趣爱好哦。探索Kube船上的世界上篇&#xff08;点击回顾&#xff09;小Phippy 搬到了船上的Pods里&#xff0c;感受到了回家般的舒适感&#xff0c;小Phippy希望能发挥一…

把文件隐藏在图片中

一、前言有的时候我们需要把文件给隐藏起来&#xff0c;但是Windows自带的隐藏方式还是很容易被发现的。这时候我们可以选择把文件放在网盘&#xff0c;但这毕竟需要网络。不过&#xff0c;我们可以通过Windows自带的功能&#xff0c;把文件隐藏在图片中。是不是有一种大隐隐于…

.NetCore下使用Polly结合IHttpClientFactory实现聚合服务

在使用微服务的过程中经常会遇到这样的情况&#xff0c;就目前我遇到的问题做下分析情况一&#xff1a;这里服务对于前后端分离情况来说&#xff0c;多使用查询服务&#xff0c;前端直接获取不同服务的数据展示&#xff0c;如果出现其中的服务失败&#xff0c;对业务数据无影响…

你需要了解的有关.NET日期时间的必要信息

引言DateTime数据类型是一个复杂的问题&#xff0c;复杂到足以让你在编写【将日期从Web服务器返回到浏览器】简单代码时感到困惑。ASP.NET MVC 5和 Web API 2/ASP.NETCore 以不同方式序列化日期&#xff0c;这可能会给在一个Web应用程序中同时使用这两个序列化的开发人员带来更…

只需3步,即可将你的Chromium Edge 浏览器设置成中文

最近&#xff0c;Chromium Edge 浏览器推出了添加语言包的功能&#xff0c;于是我们可以轻松将其界面设置成中文的。第1步: 升级浏览器到最新版在Chromium Edge 浏览器的地址栏中输入:edge://settings/help稍等片刻&#xff0c;浏览器会自行升级到最新版。第2步: 将Language se…

【北京】线下活动 | Azure SQL Database Managed Instance发布会

6/12/2019 | 8.30 AM - 1.30 PM微软大厦一号楼一层故宫会议室N丹棱街5号 海淀区 北京市S尊敬的客户感谢您一直以来对微软的支持&#xff01;诚挚地邀请您参加微软Azure SQL Database Managed Instance &#xff08;SQL Database托管实例&#xff09;在中国北京的发布会。SQL Da…

ASP.Net Core MVC 发生二次请求

Bug回忆录昨天搭建新框架的时候&#xff0c;遇到一个很奇怪的“Bug”&#xff0c;每次请求都会触发两次Aciton&#xff0c;举例子吧&#xff0c;Demo&#xff1a;_Layout.cshtmlHomeControllerIndex.cshtml<h1>Hi, Im index page.</h1>最简单不过的代码&#xff0c…

DDD战略设计相关核心概念的理解

前言本文想再讨论一下关于领域、业务、业务模型、解决方案、BC、领域模型、微服务这些概念的含义和关系。初衷是我发现现在DDD领域建模以及解决方案落地过程中&#xff0c;常常对这些概念理解不清楚或者有歧义&#xff0c;导致我们不知道如何运用这些概念来落地我们的软件。领域…

Visual Studio容器项目工程化心得

引言  关注博主的网友会看到我使用ASP.NET Core 容器化部署企业级项目的过程&#xff0c; 回想到开发过程中&#xff0c;鄙人有一些工程化心得&#xff0c; 分享给同学们。项目工程化因为本项目涉及单元测试Project、容器化部署、本地化的sqlite数据库&#xff0c;nlog日志&a…

Insider Dev Tour 2019 | 以技术之力,展现传承魅力

世界原本是一个漆黑的山洞的大小&#xff0c;一个“胆大妄为”的人燃起火把&#xff1b;世界原本是一个孤岛的轮廓&#xff0c;一个“野心勃勃”的人扬帆起航&#xff1b;如今&#xff0c;世界的版图已经清晰&#xff0c;是什么让我们走出黑暗与闭塞&#xff0c;从未放下对未知…

.NET 之 ORM 性能评测

Why你应该总能听到某ORM性能比Dapper高你应该有如下疑问&#xff1a;基准测试是否权威基准测试的方式是否合理基准测试的标准是否能够统一统一基准测试标准/规范如何进行姿势正确的性能测试相信大家对 Dapper 的性能&#xff0c;以及基准测试的权威性是没有疑问的&#xff08;否…

CF817E Choosing The Commander 01tire 贪心

看到集合和异或&#xff0c;可以想到01tire(但是我没有想到)。 让后就可以对于每次插入和删除一个数&#xff0c;都在01tire树上操作即可。让后记录一下到当前位(当然是从高位到低位啦)有相同前缀的数的个数。例如样例建图出来大概是这样的&#xff1a; 可以看到从编号为2的点开…

不断进化的分支和需求管理

昨天有朋友在公众号私信问我几个关于代码分支管理的问题&#xff0c;这几个问题是我去年写的《在团队中使用GitLab中的Merge Request工作模式》一文结尾时抛出的几个问题&#xff1a;如果系统上线后有紧急Bug需要处理&#xff0c;这个流程应该怎样去调整&#xff1f;每个任务都…

CF56E Domino Principle 树状数组 + 简单dp

一个比较简单的题&#xff0c;但是我还是没做出来(哭。 很容易想到从后往前做&#xff0c;所以我们可以维护一个dp数组f&#xff0c;f(i)表示到第i个牌倒下能达到的最远距离。 f直接倒着跑&#xff0c;每次取[x,xh−1][x,xh-1][x,xh−1]的最大值即可&#xff0c;可以用线段树比…

基于Docker的Consul服务发现集群搭建

在去年的.NET Core微服务系列文章中&#xff0c;初步学习了一下Consul服务发现&#xff0c;总结了两篇文章。本次基于Docker部署的方式&#xff0c;以一个Demo示例来搭建一个Consul的示例集群&#xff0c;最后给出一个HA的架构示范&#xff0c;也会更加贴近于实际应用环境。一、…

Hills And Valleys CodeForces - 1467B 思维

给你一个数组&#xff0c;最多可以修改一个数&#xff0c;问最少的山峰和山谷数量之和。 小菜鸡做了一年。 一上来想猜个结论&#xff0c;让每个数等于其相邻的两个数&#xff0c;看了题解之后也证明的正确性&#xff0c;当时直接写就没后面这么多事了。 但是命运让我分情况讨…

[译]使用LazZiya.ExpressLocalization开发多语言支持的ASP.NET Core 2.x项目

介绍开发多语言支持的ASP.NET Core 2.x Web应用程序需要大量的基础架构设置&#xff0c;并且耗费时间和精力。这篇文章&#xff0c;我们将使用LazZiya.ExpressLocalization nuget包一步本地化支持。背景大多数网络应用程序都是基于网址的本地化。因此我们可以在网址中看到所选的…