能過《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