public async Task <IActionResult> OnPostAsync() { Version = Assembly.GetEntryAssembly().GetName().Version.ToString(); AccountPolicyAdapterModel AccountPolicyAdapterModel = await AccountPolicyService.GetAsync(); bool checkPreLoginData = true; if (string.IsNullOrEmpty(Username) || string.IsNullOrEmpty(Password) || string.IsNullOrEmpty(Username.Trim()) || string.IsNullOrEmpty(Password.Trim())) { Msg = "帳號或者密碼不可為空白"; checkPreLoginData = false; } else if (string.IsNullOrEmpty(Captcha)) { Msg = "請輸入驗證碼"; checkPreLoginData = false; } else if (GetCaptchaSHA(Captcha) != CaptchaOrigin) { Msg = "驗證碼輸入錯誤"; checkPreLoginData = false; } if (checkPreLoginData) { #region 檢查該使用者是否已經被停用了 if (Username.ToLower() != MagicHelper.開發者帳號) { var accUser = await myUserService.UserByAccount(Username); if (accUser == null) { #region 身分驗證失敗,使用者不存在 Msg = $"身分驗證失敗,使用者帳號 ({Username}) 或者密碼不正確"; await SystemLogHelper.LogAsync(new SystemLogAdapterModel() { Message = Msg, Category = LogCategories.User, Content = "", LogLevel = LogLevels.Information, Updatetime = DateTime.Now, IP = HttpContextAccessor.GetConnectionIP(), }); logger.LogInformation($"{Msg}"); GetCaptchaImage(); return(Page()); #endregion } if (accUser.Status == false) { #region 使用者已經被停用,無法登入 Msg = $"使用者 {accUser.Account} 已經被停用,無法登入"; await SystemLogHelper.LogAsync(new SystemLogAdapterModel() { Message = Msg, Category = LogCategories.User, Content = "", LogLevel = LogLevels.Information, Updatetime = DateTime.Now, IP = HttpContextAccessor.GetConnectionIP(), }); logger.LogInformation($"{Msg}"); GetCaptchaImage(); return(Page()); #endregion } if (AccountPolicyAdapterModel.EnableLoginFailDetection) { if (accUser.LoginFailUnlockDatetime > DateTime.Now) { #region 使用者已經被鎖住,無法登入 Msg = $"使用者 {accUser.Account} 因為輸入過多錯誤密碼,已經被鎖住,無法登入"; await SystemLogHelper.LogAsync(new SystemLogAdapterModel() { Message = Msg, Category = LogCategories.User, Content = "", LogLevel = LogLevels.Information, Updatetime = DateTime.Now, IP = HttpContextAccessor.GetConnectionIP(), }); logger.LogInformation($"{Msg}"); GetCaptchaImage(); return(Page()); #endregion } } } #endregion (MyUserAdapterModel user, string message) = await myUserService.CheckUser(Username, Password); if (user == null) { #region 身分驗證失敗,使用者不存在 Msg = $"身分驗證失敗,使用者({Username}不存在 : {message})"; await SystemLogHelper.LogAsync(new SystemLogAdapterModel() { Message = Msg, Category = LogCategories.User, Content = "", LogLevel = LogLevels.Information, Updatetime = DateTime.Now, IP = HttpContextAccessor.GetConnectionIP(), }); logger.LogInformation($"{Msg}"); GetCaptchaImage(); return(Page()); #endregion } string returnUrl = Url.Content("~/"); #region 加入這個使用者需要用到的 宣告類型 Claim Type var claims = new List <Claim> { new Claim(ClaimTypes.Role, "User"), new Claim(ClaimTypes.NameIdentifier, user.Account), new Claim(ClaimTypes.Name, user.Name), new Claim(ClaimTypes.Sid, user.Id.ToString()), new Claim(MagicHelper.MenuRoleClaim, user.MenuRoleId.ToString()), new Claim(MagicHelper.MenuRoleNameClaim, user.MenuRole?.Name), new Claim(MagicHelper.LastLoginTimeClaim, DateTime.Now.Ticks.ToString()) }; #region 若為 開發人員,加入 開發人員 專屬的角色 if (MagicHelper.開發者帳號.ToString() == Username.ToLower()) { claims.Add(new Claim(ClaimTypes.Role, MagicHelper.開發者的角色聲明)); } else { if (user.ForceChangePassword == true) { returnUrl = Url.Content("~/NeedChangePassword"); } } #endregion #region 加入該使用者需要加入的相關角色 var menuDatas = user.MenuRole.MenuData .Where(x => x.Enable == true).ToList(); foreach (var item in menuDatas) { if (item.IsGroup == false) { if (item.CodeName.ToLower() != MagicHelper.開發者的角色聲明) { // 避免使用者自己加入一個 開發人員專屬 的角色 if (!((item.CodeName.Contains("/") == true || item.CodeName.ToLower().Contains("http") == true))) { claims.Add(new Claim(ClaimTypes.Role, item.CodeName)); } } } } #endregion #endregion #region 建立 宣告式身分識別 // ClaimsIdentity類別是宣告式身分識別的具體執行, 也就是宣告集合所描述的身分識別 var claimsIdentity = new ClaimsIdentity( claims, MagicHelper.CookieAuthenticationScheme); #endregion #region 建立關於認證階段需要儲存的狀態 var authProperties = new AuthenticationProperties { IsPersistent = true, RedirectUri = this.Request.Host.Value }; #endregion #region 進行使用登入 try { await HttpContext.SignInAsync( MagicHelper.CookieAuthenticationScheme, new ClaimsPrincipal(claimsIdentity), authProperties); } catch (Exception ex) { var msg = ex.Message; } #endregion Msg = $"使用者 ({Username}) 登入成功"; await SystemLogHelper.LogAsync(new SystemLogAdapterModel() { Message = Msg, Category = LogCategories.User, Content = "", LogLevel = LogLevels.Information, Updatetime = DateTime.Now, IP = HttpContextAccessor.GetConnectionIP(), }); logger.LogInformation($"{Msg}"); #region 更新使用者最後登入時間 user.LastLoginDatetime = DateTime.Now; await myUserService.UpdateAsync(user); #endregion return(LocalRedirect(returnUrl)); } GetCaptchaImage(); return(Page()); }