public class IdentityConfig { public void Configuration(IAppBuilder app) { // 默認使用CookieAuthenticationMiddleware app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, LoginPath = new PathString("/Account/Login") }); } }
在CookieAuthenticationExtensions裏定義了默認的cookieAuthentication中間件web
public static IAppBuilder UseCookieAuthentication(this IAppBuilder app, CookieAuthenticationOptions options, PipelineStage stage) { if (app == null) { throw new ArgumentNullException("app"); } // 默認中間件 app.Use(typeof(CookieAuthenticationMiddleware), app, options); app.UseStageMarker(stage); return app; }
public abstract class AuthenticationMiddleware<TOptions> : OwinMiddleware where TOptions : AuthenticationOptions { protected AuthenticationMiddleware(OwinMiddleware next, TOptions options) : base(next) { if (options == null) { throw new ArgumentNullException("options"); } Options = options; } public TOptions Options { get; set; } // 具體的執行流程很簡單,分爲建立,初始化,下一個中間件執行,卸載 public override async Task Invoke(IOwinContext context) { //獲取處理者,【cookieAuth處理類】 AuthenticationHandler<TOptions> handler = CreateHandler(); //初始化,會調用【Auth處理基類】的BaseInitializeAsync,具體查看---Initialize說明--- await handler.Initialize(Options, context); if (!await handler.InvokeAsync())//默認返回false { //調用下一個中間件,比方說調用MVC中間件 await Next.Invoke(context); } // 最後執行,會調用【Auth處理基類】的TeardownAsync,具體說明查看---Teardown說明--- await handler.TeardownAsync(); } protected abstract AuthenticationHandler<TOptions> CreateHandler(); }
---Initialize說明---
初始化的時候,將獲取已有的ticket,供後續的中間件使用
將調用【Auth處理基類】的BaseInitializeAsync來完成初始化cookie
protected async Task BaseInitializeAsync(AuthenticationOptions options, IOwinContext context) { _baseOptions = options; Context = context; Helper = new SecurityHelper(context); RequestPathBase = Request.PathBase; _registration = Request.RegisterAuthenticationHandler(this); // 設置響應事件,在teardown以後會執行 Response.OnSendingHeaders(OnSendingHeaderCallback, this); await InitializeCoreAsync(); // 主動模式時執行 if (BaseOptions.AuthenticationMode == AuthenticationMode.Active) { // 根據cookie獲得ticket,判斷是否須要renew,後續的中間件能夠獲取identity信息 AuthenticationTicket ticket = await AuthenticateAsync(); if (ticket != null && ticket.Identity != null) { // 將identity添加到context.Request.User裏 Helper.AddUserIdentity(ticket.Identity); } } }
---Teardown說明---
就是判斷是不是登陸,註銷,renew,而後處理
登陸:製做ticket寫入cookie
註銷:刪除cookie
renew(剩餘時長<使用時長):從新生成cookie的有效期app
internal async Task TeardownAsync() { // 申請響應 // 判斷是不是登陸(IAuthenticationManager.SignIn),註銷(IAuthenticationManager.SignOut),renew(_shouldRenew標誌),而後處理 await ApplyResponseAsync(); // 默認返回null await TeardownCoreAsync(); // request[key:Constants.SecurityAuthenticate],註銷AuthenticationHandler,恢復成RegisterAuthenticationHandler以前的狀態 Request.UnregisterAuthenticationHandler(_registration); }
大體的流程就是這樣,具體的如何判斷登陸,註銷,下一章再詳細講解。async