aspnetcore 認證相關類簡要說明二
能過《aspnetcore 認證相關類簡要說明一》我們已經了解如何將AuthenticationOptions註入到我們依賴註入系統。接下來,我們將了解一下IAuthenticationSchemeProvider通過AuthenticationOptions如何提供AuthenticationScheme的。aspnetcore 中IAuthenticationSchemeProvider默認實現是AuthenticationSchemeProvider,我們簡單的分析下它的源碼(以下是我簡化的源碼):
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構造方法中,將通過參數傳入給該類的對象。在構造方法中,通過foreach options對象的Schemes屬性Buid方法獲得AuthenticationScheme,以它的Name屬性作為_schemes字典的key,保存AuthenticationScheme到字典中。我們還可以通過AuthenticationSchemeProvider類的AddScheme添加認證方案。
接下來,我們繼續看看IAuthenticationHandlerProvider類實現類AuthenticationHandlerProvider:
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獲取到。
既然講到IAuthenticationHandler接口,我就簡單復制一下該接口定義的方法代碼放下面:
public interface IAuthenticationHandler { Task InitializeAsync(AuthenticationScheme scheme, HttpContext context); Task<AuthenticateResult> AuthenticateAsync(); Task ChallengeAsync(AuthenticationProperties properties); Task ForbidAsync(AuthenticationProperties properties); }
關於該接口的第一個方法,我們在上一段代碼有調用,就不解釋了。既然是認證,整個認證過程中最重要的邏輯當然實現在IAuthenticationHandler的AuthenticateAsync方法中。
本篇主要講AuthenticationSchemeProvider和IAuthenticationHandlerProvider,以及簡單提了一下IAuthenticationHandler,明天我們繼續講IAuthenticationHandler的默認實現。
由於時間已經很晚了,本篇就到此結束。
aspnetcore 認證相關類簡要說明二