1. 程式人生 > >aspnetcore 認證相關類簡要說明二

aspnetcore 認證相關類簡要說明二

provider con .cn name屬性 uil 添加 pos mea tex

能過《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 認證相關類簡要說明二