如果你使用过.NetCore开发过程序,你会很清楚,在其中我们经常会用到一些如下的代码

 services.AddAuthentication(options =>{options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;}).AddCookie("Cookies",options=>{                });

然后添加了中间件

   app.UseAuthentication();

然而这些中间内部、服务之间怎么去处授权的呢?接下来就来探讨一下。

先来说说UseAuthentication这个都做了什么事情

首先我们先来看下在判断授权的时候是用HttpContext.User中获取了身份信息,从身份中获取了IsAuthenticated来判断是否认证,通过这些我们发现其实 UseAuthentication就做了下面的事情,通过app.UseMiddleware<AuthenticationMiddleware>();中间件将身份信息写入到上下文对象中的User中

 context.User = result.Principal;

不然发现在这个过程中,会有一些相关的基础服务和配置参数,让后自然而然会想到添加注入服务,然后下面的代码就出来了,添加认证服务、以及一些初始参数的配置

services.AddAuthentication(options =>{options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;});

接下来我们来看一看AddAuthentication干了什么事情,写过扩展的朋友都知道,AddAuthentication只是一个挂载到IServiceCollection上的一个扩展方法,有参数就想到了配置所里扩展方法里面就完成了2件事情

 var builder = services.AddAuthentication();services.Configure(configureOptions);

添加授权服务和添加配置服务

这里的builder其实是AuthenticationBuilder,其实这个类也没做什么事情,就接管了下IServiceCollection服务,以便于在AuthenticationBuilder中完成对services服务调用完成其他的功能,如AddScheme

  public AuthenticationBuilder(IServiceCollection services)=> Services = services;

管道中中间件像企业的生产流水线一样,经过一层一层的加工(HttpContext=>HttpRequest、HttpRespose、IFeatureCollection、ClaimsPrincipal)等,最后返回加工好的产品,这里的认证中间件也不例外,主要就是为了附加ClaimsPrincipal而生的

这个图也不知被用了多少次了,我也用下

接下来就来看下在中间件AuthenticationMiddleware中都做了什么事情

 public static IApplicationBuilder UseAuthentication(this IApplicationBuilder app){if (app == null){throw new ArgumentNullException(nameof(app));}return app.UseMiddleware<AuthenticationMiddleware>();}

说道中间件不得不提到一个重要的东东RequestDelegate这个对象,他就想一个包裹的产品,穿梭连接在每个中间件游走,就想生产流水线上的传送产品的传送带一样,传送做请求中的各种对象

首先要获取的就是 提供的认证处理服务 IAuthenticationHandlerProvider

 var handlers = context.RequestServices.GetRequiredService<IAuthenticationHandlerProvider>();

这里还要说下的就是IAuthenticationSchemeProvider,由于授权参数指定的Scheme指定了获取授权来源,中间件需要获取当前配置的Scheme对应的IAuthenticationHandlerProvider处理服务

如果获取到就处理认证请求,这里要说明下代码,在.NetCore其他地方对下面处理请求做了接口实现,其实就是AddCookies中的CookieAuthenticationHandler,当找到对应请求就不会在处理了。

 public interface IAuthenticationRequestHandler : IAuthenticationHandler{Task<bool> HandleRequestAsync();}

可以看到这样的实现,需要什么实现就添加什么handle,只是这里AddCookie帮我们处理了

public class CookieAuthenticationHandler :AuthenticationHandler<CookieAuthenticationOptions>,IAuthenticationSignInHandler,IAuthenticationSignOutHandler{}

如果没有从授权Scheme中找到,说明未认证,需要添加认证身份信息的Scheme,获取到IAuthenticationService服务

 context.RequestServices.GetRequiredService<IAuthenticationService>().AuthenticateAsync(context, scheme);

这里实际上还是从IAuthenticationHandlerProvider服务提供,只是在IAuthenticationService服务中注入了相关服务,最终还是通过IAuthenticationHandler去实现的

public AuthenticationService(IAuthenticationSchemeProvider schemes, IAuthenticationHandlerProvider handlers, IClaimsTransformation transform){/**/}

那么登录的时候SignIn做了什么呢?

context.RequestServices.GetRequiredService<IAuthenticationService>().SignInAsync(context, scheme, principal, properties);

从认证服务中调用了SignIn,其实最终都是通过IAuthenticationHandler接口来处理的,SignIn、SignOut都是通过AddCookies中CookieAuthenticationHandler通过实现了IAuthenticationSignInHandler来处理,退出IAuthenticationSignOutHandler,认证则是实现IAuthenticationHandler接口,下面我们针对上面的来画图分析下可能要明白一些

下面在来看下AddCookie都做了什么

 public static AuthenticationBuilder AddCookie(this AuthenticationBuilder builder, string authenticationScheme, string displayName, Action<CookieAuthenticationOptions> configureOptions){builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IPostConfigureOptions<CookieAuthenticationOptions>, PostConfigureCookieAuthenticationOptions>());return builder.AddScheme<CookieAuthenticationOptions, CookieAuthenticationHandler>(authenticationScheme, displayName, configureOptions);}

这里添加好了Scheme信息,而在AddScheme中注册了CookieAuthenticationHandler服务,在这里服务中我们可以看到一个返回认证信息的一个重写方法,而最终处理认证的就是这个处理,它继承了AuthenticationHandler<Options>,而在AuthenticationHandler里面去实现了IAuthenticationHandler (Task<AuthenticateResult> AuthenticateAsync()),这个之前说的认证具体实现,下面这个是在 AuthenticationHandler<Options> [protected abstract Task<AuthenticateResult> HandleAuthenticateAsync()] 抽象重写,实际这个就是在IAuthenticationHandler (Task<AuthenticateResult> AuthenticateAsync())中来实现的

protected abstract Task<AuthenticateResult> HandleAuthenticateAsync();

  public async Task<AuthenticateResult> AuthenticateAsync(){var result = await HandleAuthenticateOnceAsync();/*.....*/return result;}

 protected Task<AuthenticateResult> HandleAuthenticateOnceAsync(){if (_authenticateTask == null){_authenticateTask = HandleAuthenticateAsync();}return _authenticateTask;}

HandleAuthenticateAsync 被CookieAuthenticationHandler 重写,后通过一些列处理返回了认证结果信息
protected override async Task<AuthenticateResult> HandleAuthenticateAsync(){/*Handle略*/return AuthenticateResult.Success(new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name));}

如此类推,总结如下:

AddCookies只是为IAuthenticationHandlerProvider中提供认证服务的来源做工作,所有会有 AddOpenIdConnect、AddJwtBearer、AddWsFederation 以及第三方扩展的 Facebook 、Google、OAuth等等

转载于:https://www.cnblogs.com/liyouming/p/9916777.html

.NetCore源码阅读笔记系列之Security (一) Authentication AddCookie相关推荐

  1. CI框架源码阅读笔记4 引导文件CodeIgniter.php

    到了这里,终于进入CI框架的核心了.既然是"引导"文件,那么就是对用户的请求.参数等做相应的导向,让用户请求和数据流按照正确的线路各就各位.例如,用户的请求url: http:// ...

  2. syzkaller 源码阅读笔记1(syz-extract syz-sysgen)

    文章目录 1. syz-extract 1-0 总结 1-1. `main()` 1-2 `archList()` - `1-1 (3)` 获取架构 name list 1-3 `createArch ...

  3. Transformers包tokenizer.encode()方法源码阅读笔记

    Transformers包tokenizer.encode()方法源码阅读笔记_天才小呵呵的博客-CSDN博客_tokenizer.encode

  4. 源码阅读笔记 BiLSTM+CRF做NER任务 流程图

    源码阅读笔记 BiLSTM+CRF做NER任务(二) 源码地址:https://github.com/ZhixiuYe/NER-pytorch 本篇正式进入源码的阅读,按照流程顺序,一一解剖. 一.流 ...

  5. 代码分析:NASM源码阅读笔记

    NASM源码阅读笔记 NASM(Netwide Assembler)的使用文档和代码间的注释相当齐全,这给阅读源码 提供了很大的方便.按作者的说法,这是一个模块化的,可重用的x86汇编器, 而且能够被 ...

  6. Yii源码阅读笔记 - 日志组件

    2015-03-09 一 By youngsterxyf 使用 Yii框架为开发者提供两个静态方法进行日志记录: Yii::log($message, $level, $category); Yii: ...

  7. AQS源码阅读笔记(一)

    AQS源码阅读笔记 先看下这个类张非常重要的一个静态内部类Node.如下: static final class Node {//表示当前节点以共享模式等待锁static final Node SHA ...

  8. 【Flink】Flink 源码阅读笔记(20)- Flink 基于 Mailbox 的线程模型

    1.概述 转载:Flink 源码阅读笔记(20)- Flink 基于 Mailbox 的线程模型 相似文章:[Flink]Flink 基于 MailBox 实现的 StreamTask 线程模型 Fl ...

  9. 【Flink】Flink 源码阅读笔记(18)- Flink SQL 中的流和动态表

    1.概述 转载:Flink 源码阅读笔记(18)- Flink SQL 中的流和动态表

最新文章

  1. debug运行可以,release运行报错的原因及修改方法
  2. css表格文字超数量就竖排_绝了,超轻量级中文 OCR,你值得拥有
  3. 【win PE】磁盘分区大小的重新调整 (再也不用担心C盘过小了)
  4. 0-1语言建模当中会遇到的问题
  5. 计算机二级mysql是什么_计算机二级mysql考什么内容?
  6. math.sqrt_Math.SQRT1_2属性与JavaScript中的示例
  7. mac下使用pyenv
  8. 拔刀剑服务器r87修复版,我的世界拔刀剑mod刀剑修复教程
  9. 按钮加ico图标_花里胡哨系列 —— 自定义U盘图标
  10. 我国博士生培养制度的现状与反思
  11. 【搜狗拼音输入法 3.2 论坛版】
  12. phpstudy建站php版本切换,phpstudy一键环境切换php版本报错,求帮忙
  13. 拉钩教育大前端课程学习-半年总结
  14. pic pwm 占空比可调 源码_PWM占空比 调节实例
  15. php实现RSA加密解密
  16. python对excel中需要的数据的单元格填充颜色
  17. seo网站关键词优化三大要素:技术 思路 执行力
  18. Excise_day01
  19. flask中的可拨插视图
  20. canvas--putImageData--(灰色滤镜、黑白滤镜、反色滤镜、模糊滤镜、马赛克滤镜)

热门文章

  1. Pixi的基本使用(5)--寻宝猎人
  2. 【前端16_辅助知识】颜色编译、色彩、网页配色技巧、PS 快捷键
  3. 国家2020年区划数据爬取
  4. 微信接口php oa,你必须了解OA与微信结合的几种方式
  5. 如何恢复 Linux 上删除的文件
  6. vs2015 web_2015年新的Web布局想法
  7. 关于企业微信服务商入门考试v2.0题库
  8. ps把下一幅画透到上一幅去_一千字值得一幅画
  9. Topic Modeling of Short Texts: A Pseudo-Document View
  10. 微软浏览器Edge在虚拟机(WIN11)中打开标签栏泛白