可能有人知道Cookie的生成由machineKey有關,machineKey用于決定Cookie生成的算法和密鑰,并如果使用多臺服務器做負載均衡時,必須指定一致的machineKey用于解密,那么這個過程到底是怎樣的呢?
如果需要在.NET Core中使用ASP.NET Cookie,本文將提到的內容也將是一些必經之路。
抽絲剝繭,一步一步分析
首先用戶通過AccountController->Login進行登錄:
//// POST: /Account/Loginpublic async Task<ActionResult> Login(LoginViewModel model, string returnUrl){ if (!ModelState.IsValid) { return View(model); } var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false); switch (result) { case SignInStatus.Success: return RedirectToLocal(returnUrl); // ......省略其它代碼 }}
它調用了SignInManager的PasswordSignInAsync方法,該方法代碼如下(有刪減):
public virtual async Task<SignInStatus> PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout){ // ...省略其它代碼 if (await UserManager.CheckPasswordAsync(user, password).WithCurrentCulture()) { if (!await IsTwoFactorEnabled(user)) { await UserManager.ResetAccessFailedCountAsync(user.Id).WithCurrentCulture(); } return await SignInOrTwoFactor(user, isPersistent).WithCurrentCulture(); } // ...省略其它代碼 return SignInStatus.Failure;}
想瀏覽原始代碼,可參見官方的Github鏈接:
https://github.com/aspnet/AspNetIdentity/blob/master/src/Microsoft.AspNet.Identity.Owin/SignInManager.cs#L235-L276
可見它先需要驗證密碼,密碼驗證正確后,它調用了SignInOrTwoFactor方法,該方法代碼如下:
private async Task<SignInStatus> SignInOrTwoFactor(TUser user, bool isPersistent){ var id = Convert.ToString(user.Id); if (await IsTwoFactorEnabled(user) && !await AuthenticationManager.TwoFactorBrowserRememberedAsync(id).WithCurrentCulture()) { var identity = new ClaimsIdentity(DefaultAuthenticationTypes.TwoFactorCookie); identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, id)); AuthenticationManager.SignIn(identity); return SignInStatus.RequiresVerification; } await SignInAsync(user, isPersistent, false).WithCurrentCulture(); return SignInStatus.Success;}
該代碼只是判斷了是否需要做雙重驗證,在需要雙重驗證的情況下,它調用了AuthenticationManager的SignIn方法;否則調用SignInAsync方法。SignInAsync的源代碼如下:
public virtual async Task SignInAsync(TUser user, bool isPersistent, bool rememberBrowser){ var userIdentity = await CreateUserIdentityAsync(user).WithCurrentCulture(); // Clear any partial cookies from external or two factor partial sign ins AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie, DefaultAuthenticationTypes.TwoFactorCookie); if (rememberBrowser) { var rememberBrowserIdentity = AuthenticationManager.CreateTwoFactorRememberBrowserIdentity(ConvertIdToString(user.Id)); AuthenticationManager.SignIn(new AuthenticationProperties { IsPersistent = isPersistent }, userIdentity, rememberBrowserIdentity); } else { AuthenticationManager.SignIn(new AuthenticationProperties { IsPersistent = isPersistent }, userIdentity); }}
新聞熱點
疑難解答