asp.net core 3.x 身份驗證-2啟動階段的配置
註冊服務、配置選項、新增身份驗證方案
在Startup.ConfigureServices執行services.AddAuthentication()
註冊如下服務(便於理解省略了部分輔助服務):
- services.TryAddScoped<IAuthenticationService, AuthenticationService>();
- services.TryAddScoped<IAuthenticationHandlerProvider, AuthenticationHandlerProvider>();
- services.TryAddSingleton<IAuthenticationSchemeProvider, AuthenticationSchemeProvider>();
整個應用的身份驗證有個選項物件叫AuthenticationOptions(上一篇有描述),允許我們對身份驗證做整體配置,這個配置主要體現為:配置系統需要支援的身份驗證方案列表;指定預設身份驗證方案、預設登入時用的身份驗證方案...預設登出...等。這個物件的應用使用asp.net core的選項模型,我們可以通過AddAuthentication(Action<AuthenticationOptions>)過載來進行配置。參考如下程式碼:
1 services.AddAuthentication(authenticationOptions=> { 2 authenticationOptions.AddScheme<CookieAuthenticationHandler>("cookie", "顯示名cookie"); 3 authenticationOptions.AddScheme<JwtBearerHandler>("jwt","顯示名jwtToken"); 4 authenticationOptions.DefaultAuthenticateScheme = "cookie"; 5 //...其它配置 6 });
此過載同樣會先註冊上面的核心服務。然後設定初始化AuthenticationOptions的委託,當某個類注入AuthenticationOptions時,依賴注入框架會呼叫此委託來初始化這個選項物件。
另一個過載AddAuthentication(string defaultAuthenticateScheme)內部也是呼叫上面的方法,只是只設置了AuthenticationOptions.DefaultAuthenticateScheme
AddAuthentication方法始終返回AuthenticationBuilder,它允許我們通過鏈式呼叫方式來向AuthenticationOptions新增多個身份驗證方案,所以更常見的方式如下:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie().AddJwtBearer();
CookieAuthenticationDefaults.AuthenticationScheme常來指明將哪個身份驗證方案作為預設。後續分別添加了cookie和JwtBearer兩個身份驗證方案。
我們說AuthenticationOptions是針對整個應用程式的身份驗證選項,可以簡單理解為它是身份驗證方案的配置時容器。針對特定身份驗證方案也有自己的配置物件。以AddCookie()為例,它等同於:
1 authenticationOptions.AddScheme<CookieAuthenticationHandler>(CookieAuthenticationDefaults.AuthenticationScheme, "顯示名cookie",); 2 service.Configre<CookieAuthenticationOptions>(options=>{ 4 options.Cookie.Name = CookieAuthenticationDefaults.CookiePrefix + name; 6 options.CookieManager = new ChunkingCookieManager(); 7 options.LoginPath = CookieAuthenticationDefaults.LoginPath; 8 options.LogoutPath = CookieAuthenticationDefaults.LogoutPath; 9 options.AccessDeniedPath = CookieAuthenticationDefaults.AccessDeniedPath; 10 } 11 });
CookieAuthenticationOptions就是針對這個cookie身份驗證方案的選項物件,將來某個類注入此選項物件時,依賴注入框架會回撥此委託來初始化它。參考:選項模型。當然AddCookie有對應的過載允許我們自己的委託來初始化這個選項物件。類似下面的程式碼:
1 services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie("換個方案名","顯示名",opt=> { 2 opt.SlidingExpiration = true;//滑動過期? 3 //設定其它跟cookie身份驗證相關的東東... 4 }).AddJwtBearer();
現在看看這段程式碼就親切多了。
身份驗證方案執行時容器AuthenticationSchemeProvider的建立
由於AuthenticationSchemeProvider是以單例形式註冊到依賴注入容器中的,因此應該在註冊時(不是很確定,假設吧)就會建立AuthenticationSchemeProvider,它通的建構函式定義了IOptions<AuthenticationOptions>引數,上面說了AuthenticationOptions就包含上面註冊進去的身份驗證方案列表,AuthenticationSchemeProvider在建構函式中遍歷,將所有註冊的身份驗證方案儲存到自身的 IDictionary<string, AuthenticationScheme> _schemes 變數中
插入身份驗證中介軟體
上面只是註冊了身份驗證過程中需要的服務並配置了應用需要支援身份驗證方案列表,在將來請求抵達時需要一箇中間件來處理身份驗證,核心任務是找到預設身份驗證處理器,通過它從請求中獲得當前使用者標識,然後設定到httpContext.User屬性上,至於處理的具體過程將在下一篇基於cookie的身份驗證整體流程詳細說。在Startup.Configre中通過擴充套件方法註冊:
app.UseRouting();
app.UseAuthentication();
app.UseEndpoints(endpoints =>{
endpoints.MapRazorPages();
});
至於為啥身份驗證中介軟體一定要在 app.UseRouting(); 之後,我是真的想不通