.NetCore原始碼閱讀筆記系列之HttpAbstractions(五) Authentication
說道認證&授權其實這塊才是核心,這款跟前面Security這塊有者緊密的聯絡,當然 HttpAbstractions 不光是認證、授權、還包含其他Http服務和中間價
接下來先就認證這塊結合前面的Security作一個補充說明
前面 AddCookie 、OpenIdConnect、Google、QQ 等等不過是新增的認證策略方式,他們實現的授權介面都來至於我們的HttpAbstractions模組中的Authentication
只不過前面封裝了擴充套件,看上起好像有點繞,比如OpenIdConnect我們來看下
builder.AddRemoteScheme<OpenIdConnectOptions, OpenIdConnectHandler>(authenticationScheme, displayName, configureOptions);
我之前說了的OpenIdConnectHandler的重要性,這個其實只不過實現了HttpAbstractions 模組下 Authentication中的抽象模組中的類及認證介面服務提供實現,可以看到OpenIdConnet 新增的遠端認證策略AddRemoteScheme,實際就是 HttpAbstractions 中Authentication中的IAuthenticationHandler介面處理以及先關IAuthenticationSignInHandler、IAuthenticationSignOutHandler的實現,包括在OpenIdConnect 或者 Cookies等裡面呼叫的SignIn SginOut 等操作,而通過下面的程式碼來實現
await handler.SignInAsync(principal, properties);
這裡有一些疑問就是hanlder 是什麼呢?這裡就是提到前面的 AddScheme中策略問題了,其實就是提供認證處理介面
public IAuthenticationHandlerProvider Handlers { get; }
說道這裡,就需要提到軟體設計中經常會用到的一個步驟,那就是 Build 、Provider 、Handler 看到這三個東西是不是很熟悉
接下來我們來看下 AuthenticationSchemeBuilder 中的 Build構建,構建的時候指定了HandlerType ,其實這裡的 HandlerType就是在AddScheme中指定了具體處理方式,注意這裡的指定方式需要繼承IAuthenticationHandler,當然也是在這裡去構建
public void AddScheme<THandler>(string name, string displayName) where THandler : IAuthenticationHandler => AddScheme(name, b => { b.DisplayName = displayName; b.HandlerType = typeof(THandler); });
其實我們可以這樣來描述,我們現在在ConfigureServices新增好自己授權服務,假定我們沒有引數,結合之前的OpenIdConnect例子,AddAuthenticationCore 、AddAuthentication其實都是擴充套件方法而已,裡面其實實現了
IAuthenticationService 、IAuthenticationHandlerProvider、IAuthenticationSchemeProvider等服務的註冊,下面我們這樣來寫,這裡的CustomHandler是我自定義的處理策略handlertype,當然這裡需要實現介面IAuthenticationHandler,當然還可以實現簽入、簽出相關介面
services.AddAuthenticationCore(options => { options.AddScheme<CustomHandler>("name", "displayname"); });
public class CustomHandler : IAuthenticationHandler { public Task<AuthenticateResult> AuthenticateAsync() { throw new NotImplementedException(); } public Task ChallengeAsync(AuthenticationProperties properties) { throw new NotImplementedException(); } public Task ForbidAsync(AuthenticationProperties properties) { throw new NotImplementedException(); } public Task InitializeAsync(AuthenticationScheme scheme, HttpContext context) { throw new NotImplementedException(); } }
其實這裡自己封裝成一個類庫其實就是類是AddOpenIdConnect這樣的認證服務中介軟體了,比如我前面寫的 AddCustom,然而你寫了這些之後怎麼來實現認證的呢?
這裡就需要說到 UserAuthentication這個中介軟體了,下面我們來看下這個中介軟體處理什麼? 其實說到這裡就已經很清楚了,就是拿到認證服務提供,呼叫Handler處理認證,然後將認證資訊寫入到User中,下面就是AuthenticationMiddleware中介軟體要做的事情
var handlers = context.RequestServices.GetRequiredService<IAuthenticationHandlerProvider>(); foreach (var scheme in await Schemes.GetRequestHandlerSchemesAsync()) { var handler = await handlers.GetHandlerAsync(context, scheme.Name) as IAuthenticationRequestHandler; if (handler != null && await handler.HandleRequestAsync()) { return; } } var defaultAuthenticate = await Schemes.GetDefaultAuthenticateSchemeAsync(); if (defaultAuthenticate != null) { var result = await context.AuthenticateAsync(defaultAuthenticate.Name); if (result?.Principal != null) { context.User = result.Principal; } } await _next(context);
通過這些文字,相信基本多這塊有大志的瞭解了,希望能夠幫助到大家