今天我们再来了解一个很重要的接口IAuthenticationService的实现类AuthenticationService:

  1. public class AuthenticationService : IAuthenticationService
  2. {
  3. public AuthenticationService(IAuthenticationSchemeProvider schemes, IAuthenticationHandlerProvider handlers, IClaimsTransformation transform)
  4. {
  5. Schemes = schemes;
  6. Handlers = handlers;
  7. Transform = transform;
  8. }
  9.  
  10. public IAuthenticationSchemeProvider Schemes { get; }
  11. public IAuthenticationHandlerProvider Handlers { get; }
  12. public IClaimsTransformation Transform { get; }
  13.  
  14. public virtual async Task<AuthenticateResult> AuthenticateAsync(HttpContext context, string scheme)
  15. {
  16. if (scheme == null)
  17. {
  18. var defaultScheme = await Schemes.GetDefaultAuthenticateSchemeAsync();
  19. scheme = defaultScheme?.Name;
  20. if (scheme == null)
  21. {
  22. throw new InvalidOperationException($"No authenticationScheme was specified, and there was no DefaultAuthenticateScheme found.");
  23. }
  24. }
  25.  
  26. var handler = await Handlers.GetHandlerAsync(context, scheme);
  27. if (handler == null)
  28. {
  29. throw await CreateMissingHandlerException(scheme);
  30. }
  31.  
  32. var result = await handler.AuthenticateAsync();
  33. if (result != null && result.Succeeded)
  34. {
  35. var transformed = await Transform.TransformAsync(result.Principal);
  36. return AuthenticateResult.Success(new AuthenticationTicket(transformed, result.Properties, result.Ticket.AuthenticationScheme));
  37. }
  38. return result;
  39. }
  40.  
  41. /// <summary>
  42. /// Challenge the specified authentication scheme.
  43. /// </summary>
  44. /// <param name="context">The <see cref="HttpContext"/>.</param>
  45. /// <param name="scheme">The name of the authentication scheme.</param>
  46. /// <param name="properties">The <see cref="AuthenticationProperties"/>.</param>
  47. /// <returns>A task.</returns>
  48. public virtual async Task ChallengeAsync(HttpContext context, string scheme, AuthenticationProperties properties)
  49. {
  50. if (scheme == null)
  51. {
  52. var defaultChallengeScheme = await Schemes.GetDefaultChallengeSchemeAsync();
  53. scheme = defaultChallengeScheme?.Name;
  54. if (scheme == null)
  55. {
  56. throw new InvalidOperationException($"No authenticationScheme was specified, and there was no DefaultChallengeScheme found.");
  57. }
  58. }
  59.  
  60. var handler = await Handlers.GetHandlerAsync(context, scheme);
  61. if (handler == null)
  62. {
  63. throw await CreateMissingHandlerException(scheme);
  64. }
  65.  
  66. await handler.ChallengeAsync(properties);
  67. }
  68.  
  69. /// <summary>
  70. /// Forbid the specified authentication scheme.
  71. /// </summary>
  72. public virtual async Task ForbidAsync(HttpContext context, string scheme, AuthenticationProperties properties)
  73. {
  74. if (scheme == null)
  75. {
  76. var defaultForbidScheme = await Schemes.GetDefaultForbidSchemeAsync();
  77. scheme = defaultForbidScheme?.Name;
  78. ...
  79. }
  80.  
  81. var handler = await Handlers.GetHandlerAsync(context, scheme);
           ...await handler.ForbidAsync(properties);
  82. }
  83.  
  84. /// <summary>
  85. /// Sign a principal in for the specified authentication scheme.
  86. /// </summary>
  87. public virtual async Task SignInAsync(HttpContext context, string scheme, ClaimsPrincipal principal, AuthenticationProperties properties)
  88. {
           ...
           if (scheme == null)
  89. {
  90. var defaultScheme = await Schemes.GetDefaultSignInSchemeAsync();
  91. scheme = defaultScheme?.Name;
  92. ...
  93. }
  94.  
  95. var handler = await Handlers.GetHandlerAsync(context, scheme);
  96. ...
           var signInHandler = handler as IAuthenticationSignInHandler;
  97. ...
           await signInHandler.SignInAsync(principal, properties);
  98. }
  99.  
  100. /// <summary>
  101. /// Sign out the specified authentication scheme.
  102. /// </summary>
  103. public virtual async Task SignOutAsync(HttpContext context, string scheme, AuthenticationProperties properties)
  104. {
  105. if (scheme == null)
  106. {
  107. var defaultScheme = await Schemes.GetDefaultSignOutSchemeAsync();
  108. scheme = defaultScheme?.Name;
  109. if (scheme == null)
  110. {
  111. throw new InvalidOperationException($"No authenticationScheme was specified, and there was no DefaultSignOutScheme found.");
  112. }
  113. }
  114.  
  115. var handler = await Handlers.GetHandlerAsync(context, scheme);
  116. if (handler == null)
  117. {
  118. throw await CreateMissingSignOutHandlerException(scheme);
  119. }
  120.  
  121. var signOutHandler = handler as IAuthenticationSignOutHandler;
  122. if (signOutHandler == null)
  123. {
  124. throw await CreateMismatchedSignOutHandlerException(scheme, handler);
  125. }
  126.  
  127. await signOutHandler.SignOutAsync(properties);
  128. }
    }

该类通过构造方法,将我们前两篇中讲到了IAuthenticationSchemeProvider和IAuthenticationHandlerProvider注入了进来,第三个参数不是很重要就飘过了。接下来我们看看它的这几个方法AuthenticateAsync、ChallengeAsync、ForbidAsync、SignInAsync和SignOutAsync等方法,他们的套路几乎都一样的,通过注入进来的两个接口的实例,最终获得到IAuthenticationHandler接口实例,并调用同名方法。

关于IAuthenticationService、IAuthenticationHandlerProvider和IAuthenticationSchemeProvider我们又是什么时候注入到服务容器里去的呢?它是在AuthenticationCoreServiceCollectionExtensions这个静态类中的AddAuthenticationCore扩展方法注入到容器中的,还有AuthenticationOptions也是在这里注入到依赖注入系统的容器中的:

  1. public static class AuthenticationCoreServiceCollectionExtensions
  2. {
  3. public static IServiceCollection AddAuthenticationCore(this IServiceCollection services)
  4. {
           ...
  5. services.TryAddScoped<IAuthenticationService, AuthenticationService>();
  6. services.TryAddSingleton<IClaimsTransformation, NoopClaimsTransformation>(); // Can be replaced with scoped ones that use DbContext
  7. services.TryAddScoped<IAuthenticationHandlerProvider, AuthenticationHandlerProvider>();
  8. services.TryAddSingleton<IAuthenticationSchemeProvider, AuthenticationSchemeProvider>();
  9. return services;
  10. }
  11.  
  12. public static IServiceCollection AddAuthenticationCore(this IServiceCollection services, Action<AuthenticationOptions> configureOptions) {
  13. ...
  14. services.AddAuthenticationCore();
  15. services.Configure(configureOptions);
  16. return services;
  17. }
  18. }

该扩展方法是在Startup的ConfigureServices方法调用的。这个就不贴代码了。

注入完以后呢?怎么使用呢?为了方便使用,aspnetcore为我们在外面又裹了一层,那就是AuthenticationHttpContextExtensions为HttpContext添加的扩展方法。我们可以在Controller如下调用:

  1. public class HomeController : Controller
  2. {
  3. public IActionResult Index()
  4. {
  5. var result = HttpContext.AuthenticateAsync();
  6. return View(result.Result);
  7. }
  8. }

至此认证相关的核心元素介绍完成,本篇到此结束。

aspnetcore 认证相关类简要说明三的更多相关文章

  1. aspnetcore 认证相关类简要说明二

    能过<aspnetcore 认证相关类简要说明一>我们已经了解如何将AuthenticationOptions注入到我们依赖注入系统.接下来,我们将了解一下IAuthenticationS ...

  2. aspnetcore 认证相关类简要说明一

    首先我想要简要说明是AuthenticationScheme类,每次看到Scheme这个单词我就感觉它是一个很高大上的单词,其实简单翻译过来就是认证方案的意思.既然一种方案,那我们就要知道这个方案的名 ...

  3. 4 Handler相关类——Live555源码阅读(一)基本组件类

    这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. Handler相关类概述 处理程序相关类一共有三个,其没有派生继承关系,但是其有友元关系和使用关系 ...

  4. iOS开发RunLoop学习:三:Runloop相关类(source和Observer)

    一:RunLoop相关类: 其中:source0指的是非基于端口por,说白了也就是处理触摸事件,selector事件,source1指的是基于端口的port:是处理系统的一些事件 注意:创建一个Ru ...

  5. Android随笔之——Android时间、日期相关类和方法

    今天要讲的是Android里关于时间.日期相关类和方法.在Android中,跟时间.日期有关的类主要有Time.Calendar.Date三个类.而与日期格式化输出有关的DateFormat和Simp ...

  6. 21 BasicTaskScheduler基本任务调度器(一)——Live555源码阅读(一)任务调度相关类

    21_BasicTaskScheduler基本任务调度器(一)——Live555源码阅读(一)任务调度相关类 BasicTaskScheduler基本任务调度器 BasicTaskScheduler基 ...

  7. MFC编程入门之十三(对话框:属性页对话框及相关类的介绍)

    前面讲了模态对话框和非模态对话框,本节来将一种特殊的对话框--属性页对话框. 属性页对话框的分类 属性页对话框想必大家并不陌生,XP系统中桌面右键点属性,弹出的就是属性页对话框,它通过标签切换各个页面 ...

  8. android 6.0 SDK中删除HttpClient的相关类的解决方法

    一.出现的情况 在eclipse或 android studio开发, 设置android SDK的编译版本为23时,且使用了httpClient相关类的库项目:如android-async-http ...

  9. Web---演示Servlet的相关类、下载技术、线程问题、自定义404页面

    Servlet的其他相关类: ServletConfig – 代表Servlet的初始化配置参数. ServletContext – 代表整个Web项目. ServletRequest – 代表用户的 ...

随机推荐

  1. JDK中ClassLoader的分类以及ClassLoader间的层次关系

    几个常见的ClassLoader: bootstrap  class  loader: 最早启动的class  loader,一般使用C语言,汇编语言,或是c++写的,用操作系统本地语言写的.这个cl ...

  2. 第2章—装配Bean—通过java代码装配bean

    通过java代码装配bean ​ 在进行显式装配的时候,有两种选型方案:java和XML配置,这里先介绍java的配置方式. 2.3.1创建配置类 先复习下上一章的配置内容: @Configurati ...

  3. 【转载】log4j详解使用

    log4j详解 日志论    在应用程序中输出日志有有三个目的:(1)监视代码中变量的变化情况,把数据周期性地记录到文件中供其他应用进行统计分析工作. (2)跟踪代码运行进轨迹,作为日后审计的依据.  ...

  4. python-cgi-demo

    简单的Python CGI 在linux平台实现注意:路径是以当前路径为根目录 ,Python文件一般放在/cgi-bin/目录下在linux命令行运行:python  -m  CGIHTTPServ ...

  5. C#中的委托 Delegate(委托 也叫代表,代表一类方法)

    1. 委托类似与 C或C++中的函数指针,但委托是 面向对象的,并且是类型安全的 详情可查看官方文档:https://msdn.microsoft.com/en-us/library/ms173172 ...

  6. Spring中使用JMS

    JMS为了Java开发人员与消息代理(message broker)交互和收发消息提供了一套标准API.而且,由于每个message broker都支持JMS,所以我们就不需要学习额外的消息API了. ...

  7. MVC中学到的小知识(MVC中的跳转,传参)

    1.mvc中视图中的href="XXX",这个XXX是控制器地址,不是另一个视图.(这里的href语句只能转向控制器,不能直接转向视图),如果要实现转向视图,可以先转到控制器,然后 ...

  8. block中self关键字的使用-防止self 被retain一次

    在代码块中使用对象的成员时(成员变量是属性strong,MRC估计是retain时效果一样,使用方法时也一样): 警告: capturing self strongly in this block i ...

  9. iptables-linux(ls)-inode-block

    Part1:iptables 环境:centos6.7 目前我只配置了INPUT.OUTPUT和FORWORD都是ACCEPT的规则 由于想要先实现防火墙规则,所以前面的内容讲的是方法,后面是详解ip ...

  10. Oracle数据库基本操作(三) —— DQL相关内容说明及应用

    本文所使用的查询表来源于oracle数据中scott用户中的emp员工表和dept部门表. 一.基本语法 SQL语句的编写顺序: select 输出的列 from 表名 where 条件 group ...