问题引入:

  我们知道当请求通过认证模块时,会给当前的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):

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

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

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

 

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

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

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

  使用

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

  当我们的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解析出来了

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

 

  让所有每个子类都继承了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 

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

  1. Asp.Net Core基于JWT认证的数据接口网关Demo

    Asp.Net Core基于JWT认证的数据接口网关Demo 近日,应一位朋友的邀请写了个Asp.Net Core基于JWT认证的数据接口网关Demo.朋友自己开了个公司,接到的一个升级项目,客户要求 ...

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

    从ASP.NET 4.x到ASP.NET Core,内置身份验证已从基于角色的访问控制(RBAC)转变为基于声明的访问控制(CBAC). 我们常用的HttpContext.User属性ASP.NET ...

  3. Asp.Net Core Docker镜像更新系统从wheezy改为stretch

    之前写过一个在Asp.Net Core里调用System.Drawing.Common绘图的DEMO,部署到Docker里运行,需要更新Asp.Net Core镜像的操作系统. https://www ...

  4. Asp.net Core基于MVC框架实现PostgreSQL操作

    简单介绍 Asp.net Core最大的价值在于跨平台.跨平台.跨平台.重要的事情说三遍.但是目前毕竟是在开发初期,虽然推出了1.0.0 正式版,但是其实好多功能还没有完善.比方说编译时的一些文件编码 ...

  5. asp.net core中IHttpContextAccessor和HttpContextAccessor的妙用

    分享一篇文章,关于asp.net core中httpcontext的拓展. 现在,试图围绕HttpContext.Current构建你的代码真的不是一个好主意,但是我想如果你正在迁移一个企业类型的应用 ...

  6. ASP.NET Core【在线教育系统】功能要求

    目录 1. 技术介绍 2.功能介绍 3. 前端 3.1 首页 3.2 课程 3.3 登入 ​ 3.4 商品兑换 3.5 课程发布 4. 后端 4.1 登录 4.2 系统管理 4.3 课程管理 4.4 ...

  7. ASP.NET Core 基于角色的 JWT 令牌

    原文:https://bit.ly/3vYljq3 作者:Rick Strahl 翻译:精致码农-王亮 声明:我翻译技术文章不是逐句翻译的,而是根据我自己的理解来表述的.其中可能会去除一些本人实在不知 ...

  8. ASP.NET Core 基于SignalR实时通讯的前后端分离技术

    环境 Visual Studio 2019 ASP.NET Core 3.1 创建项目 从菜单中选择文件>新建项目. 在创建新项目对话框中,选择ASP.NET Core Web 应用程序,然后选 ...

  9. ASP.NET Core 基于JWT的认证(二)

    上一节我们对 Jwt 的一些基础知识进行了一个简单的介绍,这一节我们将详细的讲解,本次我们将详细的介绍一下 Jwt在 .Net Core 上的实际运用. .Net Core 2.2 Visual St ...

最新文章

  1. libgdx使用android控件,在Android上使用libGDX中的SQLite
  2. 推荐一个高质量的git命名查询和学习的github仓库git-recipes
  3. 开源项目导入eclipse的一般步骤[转]
  4. python copy函数用法_python shutil模块函数copyfile和copy的区别
  5. ASA 5.0/8.0/9.0 杂记
  6. vision安装过程中出错_scrapy安装过程中之Twisted的安装遇到的坑
  7. (九)特征提取之主成分分析(PCA)
  8. 使用Jsoup 抓取页面的数据
  9. sql日志文件查看工具
  10. 用python爬虫,pyinstaller写一个属于自己的彩虹屁生成器!(链接在文末自取)
  11. 区块链技术应用在金融领域之大数据风控
  12. dataframe两个表合并_python处理DataFrame数据的一些常用操作
  13. 面试官:为什么 0.1 + 0.2 == 0.300000004 ?
  14. Makefile中wildcard使用方法
  15. 傅里叶级数构建信号要求频率有正有负_电子科大学长说—信号与系统考研例题详解重点习题...
  16. 第四方汇聚支付接口对接Php
  17. access 有效性规则和有效性文本
  18. 基于Java代码自动提交Spark任务
  19. 如何查看mysql库中表的创建语句
  20. 微信小程序客服相关功能

热门文章

  1. t30智能插座怎么设置_如何设置ConnectSense智能插座
  2. 框架基础:深入理解Java注解类型(@Annotation)
  3. 【算法】LeetCode算法题-Maximum Subarray
  4. css 中图片旋转,倾斜,位移,平滑
  5. 在微信小程序中绘制图表(part2)
  6. 完全卸载mysql数据库图文教程
  7. 常用的加密算法---数字摘要
  8. 开发们 点广告-赚点BT币
  9. Jafka源码粗略解读之二--关于JMX
  10. 敏捷个人:提供更多文档下载,并转载一篇敏捷个人读书笔记