能过《aspnetcore 认证相关类简要说明一》咱们已经了解如何将AuthenticationOptions注入到咱们依赖注入系统。接下来,咱们将了解一下IAuthenticationSchemeProvider经过AuthenticationOptions如何提供AuthenticationScheme的。aspnetcore 中IAuthenticationSchemeProvider默认实现是AuthenticationSchemeProvider,咱们简单的分析下它的源码(如下是我简化的源码):html
public class AuthenticationSchemeProvider : IAuthenticationSchemeProvider {
private readonly IDictionary<string, AuthenticationScheme> _schemes;
... public AuthenticationSchemeProvider(IOptions<AuthenticationOptions> options)
{
foreach(var scheme in options.Schemes){
var authenticationScheme=scheme.Build();
_schemes.Add(authenticationScheme.Name,authenticationScheme);
}
}
... public virtual Task<AuthenticationScheme> GetSchemeAsync(string name)
{
return Task.FromResult(_schemes[name]);
}
public virtual void AddScheme(AuthenticationScheme scheme);
}
还记得咱们上篇文章中经过services.AddAuthentication注入AuthenticationOptions吗?在AuthenticationSchemeProvider构造方法中,将经过依赖注入系统将AuthenticationOptions传入给该类做为参数。在构造方法中,经过foreach options对象的Schemes属性Buid方法得到AuthenticationScheme,以它的Name属性做为_schemes字典的key,保存AuthenticationScheme到字典中。咱们还能够经过AuthenticationSchemeProvider类的AddScheme添加认证方案。async
接下来,咱们继续看看IAuthenticationHandlerProvider类实现类AuthenticationHandlerProvider:ide
public class AuthenticationHandlerProvider : IAuthenticationHandlerProvider { public AuthenticationHandlerProvider(IAuthenticationSchemeProvider schemes) { Schemes = schemes; } public IAuthenticationSchemeProvider Schemes { get; } private Dictionary<string, IAuthenticationHandler> _handlerMap = new Dictionary<string, IAuthenticationHandler>(StringComparer.Ordinal); public async Task<IAuthenticationHandler> GetHandlerAsync(HttpContext context, string authenticationScheme) { if (_handlerMap.ContainsKey(authenticationScheme)) { return _handlerMap[authenticationScheme]; } var scheme = await Schemes.GetSchemeAsync(authenticationScheme); ...
var handler = (context.RequestServices.GetService(scheme.HandlerType) ?? ActivatorUtilities.CreateInstance(context.RequestServices, scheme.HandlerType)) as IAuthenticationHandler; if (handler != null) { await handler.InitializeAsync(scheme, context); _handlerMap[authenticationScheme] = handler; } return handler; } }
该类实现仍是比较简单的,经过构造方法,将IAuthenticationSchemeProvider注入进来,该类最重要的方法也是该类除了构造方法以外的惟一方法GetHandlerAsync。还记得我在上篇特别提醒注意AuthenticationOptions类的AddScheme<THandler>方法中THandler必须是IAuthenticationHandler接口类型吗?咱们就是经过该类的GetHandlerAsync获取到咱们在Startup的ConfigureServices注入的认证方案处理类型MyAuth类的实例。post
既然讲到IAuthenticationHandler接口,我就简单复制一下该接口定义的方法代码放下面:ui
public interface IAuthenticationHandler { Task InitializeAsync(AuthenticationScheme scheme, HttpContext context); Task<AuthenticateResult> AuthenticateAsync(); Task ChallengeAsync(AuthenticationProperties properties); Task ForbidAsync(AuthenticationProperties properties); }
关于该接口的第一个方法,咱们在上一段代码有调用,就不解释了。既然是认证,整个认证过程当中最重要的逻辑固然实如今IAuthenticationHandler的AuthenticateAsync方法中。spa
本篇主要讲AuthenticationSchemeProvider和IAuthenticationHandlerProvider,以及简单提了一下IAuthenticationHandler,明天咱们继续讲IAuthenticationHandler的默认实现。code
因为时间已经很晚了,本篇就到此结束。htm