public async Task <IActionResult> Login(LoginInputModel model, string button) { var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl); if (button != "login") { // the user clicked the "cancel" button if (context != null) { // if the user cancels, send a result back into IdentityServer as if they // denied the consent (even if this client does not require consent). // this will send back an access denied OIDC error response to the client. await _interaction.GrantConsentAsync(context, ConsentResponse.Denied); // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null return(Redirect(model.ReturnUrl)); } else { // since we don't have a valid context, then we just go back to the home page return(Redirect("~/")); } } if (ModelState.IsValid) { // validate username/password against in-memory store if (_users.ValidateCredentials(model.Username, model.Password)) { if (context.ClientId.Contains("saml")) { context.Tenant = context.ClientId; } var user = _users.FindByUsername(model.Username); await _events.RaiseAsync(new UserLoginSuccessEvent(user.Username, user.SubjectId, user.Username)); user.Claims.Add(new Claim("tenant", context.Tenant.Split(".").First())); // only set explicit expiration here if user chooses "remember me". // otherwise we rely upon expiration configured in cookie middleware. AuthenticationProperties props = null; if (AccountOptions.AllowRememberLogin && model.RememberLogin) { props = new AuthenticationProperties { IsPersistent = true, ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration) }; } ; var claims = user.Claims.ToArray(); // issue authentication cookie with subject ID and username await HttpContext.SignInAsync(user.SubjectId, user.Username, props, claims); // make sure the returnUrl is still valid, and if so redirect back to authorize endpoint or a local page if (_interaction.IsValidReturnUrl(model.ReturnUrl) || Url.IsLocalUrl(model.ReturnUrl)) { return(Redirect(model.ReturnUrl)); } return(Redirect("~/")); } await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, "invalid credentials")); ModelState.AddModelError("", AccountOptions.InvalidCredentialsErrorMessage); } // something went wrong, show form with error var vm = await _account.BuildLoginViewModelAsync(model); return(View(vm)); }
public async Task <IActionResult> Login(LoginInputModel model, string button) { // check if we are in the context of an authorization request var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl); // the user clicked the "cancel" button if (button != "login") { if (context != null) { // if the user cancels, send a result back into IdentityServer as if they // denied the consent (even if this client does not require consent). // this will send back an access denied OIDC error response to the client. await _interaction.GrantConsentAsync(context, ConsentResponse.Denied); // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null if (await _clientStore.IsPkceClientAsync(context.ClientId)) { // if the client is PKCE then we assume it's native, so this change in how to // return the response is for better UX for the end user. return(View("Redirect", new RedirectViewModel { RedirectUrl = model.ReturnUrl })); } return(Redirect(model.ReturnUrl)); } else { // since we don't have a valid context, then we just go back to the home page return(Redirect("~/")); } } if (ModelState.IsValid) { // validate username/password against in-memory store if (_users.ValidateCredentials(model.Username, model.Password)) { var user = _users.FindByUsername(model.Username); await _events.RaiseAsync(new UserLoginSuccessEvent(user.Username, user.SubjectId, user.Username, clientId : context?.ClientId)); // only set explicit expiration here if user chooses "remember me". // otherwise we rely upon expiration configured in cookie middleware. AuthenticationProperties props = null; if (AccountOptions.AllowRememberLogin && model.RememberLogin) { props = new AuthenticationProperties { IsPersistent = true, ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration) }; } ; // issue authentication cookie with subject ID and username await HttpContext.SignInAsync(user.SubjectId, user.Username, props); if (context != null) { if (await _clientStore.IsPkceClientAsync(context.ClientId)) { // if the client is PKCE then we assume it's native, so this change in how to // return the response is for better UX for the end user. return(View("Redirect", new RedirectViewModel { RedirectUrl = model.ReturnUrl })); } // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null return(Redirect(model.ReturnUrl)); } // request for a local page if (Url.IsLocalUrl(model.ReturnUrl)) { return(Redirect(model.ReturnUrl)); } else if (string.IsNullOrEmpty(model.ReturnUrl)) { return(Redirect("~/")); } else { // user might have clicked on a malicious link - should be logged throw new Exception("invalid return URL"); } } await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, "invalid credentials", clientId : context?.ClientId)); ModelState.AddModelError(string.Empty, AccountOptions.InvalidCredentialsErrorMessage); } // something went wrong, show form with error var vm = await BuildLoginViewModelAsync(model); return(View(vm)); }
public async Task <IActionResult> Login(LoginModel login) { if (login.Action.ToLower() == "cancel") { var request = await _interaction.GetAuthorizationContextAsync(login.ReturnUrl); if (request != null) { ConsentResponse grantedConsent = ConsentResponse.Denied; await _interaction.GrantConsentAsync(request, grantedConsent); return(Redirect(login.ReturnUrl)); } else { //异常处理 } } if (ModelState.IsValid) { var user = _userStore.FindByUsername(login.UserName); if (user != null && _userStore.ValidateCredentials(user.Username, user.Password)) { #region 刚开始这样登录是不行的 var claims = new List <Claim> { new Claim("name", login.UserName) }; var claimIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); var claimsPrincipal = new ClaimsPrincipal(claimIdentity); //这种方式是cookie认证,这样登录无效 //await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, // claimsPrincipal, // new AuthenticationProperties // { // IsPersistent = true, // // ExpiresUtc = DateTime.Now.AddDays(5) // }); //var claims1 = new List<Claim> { // new Claim(JwtClaimTypes.Subject,user.SubjectId), // new Claim(JwtClaimTypes.Name,user.Username) // }; //var claimIdentity1 = new ClaimsIdentity(claims1, CookieAuthenticationDefaults.AuthenticationScheme); //var claimsPrincipal1 = new ClaimsPrincipal(claimIdentity1); //await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, // claimsPrincipal1, // new AuthenticationProperties // { // IsPersistent = true, // // ExpiresUtc = DateTime.Now.AddDays(5) // }); #endregion #region 这样登录才正确 var p = new AuthenticationProperties { IsPersistent = true, ExpiresUtc = DateTime.Now.AddDays(5) }; //identityserver 是身份验证 ,identity 所以要用该方法 /* * */ //Microsoft.AspNetCore.Http.AuthenticationManagerExtensions.SignInAsync(HttpContext, user.SubjectId, user.Username, p); //或者 await HttpContext.SignInAsync(user.SubjectId, user.Username, p); //登录成功,跳转到同意授权页面 return(Redirect(login.ReturnUrl)); #endregion } } //else return(View("login")); }
public JsonResult MakeCredentialOptions([FromForm] string username, [FromForm] string displayName, [FromForm] string attType, [FromForm] string authType, [FromForm] bool requireResidentKey, [FromForm] string userVerification) { try { // user must already exist in Identity var identityUser = _users.FindByUsername(username); if (identityUser == null) { throw new Exception("User not found"); } if (!HttpContext.User.IsAuthenticated()) { throw new Exception("User is not authenticated"); } ; // 1. Get user from DB by username (in our example, auto create missing users) var user = PasswordlessStore.GetOrAddUser(username, () => new Fido2User { DisplayName = displayName, Name = username, Id = Encoding.UTF8.GetBytes(username) // byte representation of userID is required }); // 2. Get user existing keys by username var existingKeys = PasswordlessStore.GetCredentialsByUser(user).Select(c => c.Descriptor).ToList(); // 3. Create options var authenticatorSelection = new AuthenticatorSelection { RequireResidentKey = requireResidentKey, UserVerification = userVerification.ToEnum <UserVerificationRequirement>() }; if (!string.IsNullOrEmpty(authType)) { authenticatorSelection.AuthenticatorAttachment = authType.ToEnum <AuthenticatorAttachment>(); } var exts = new AuthenticationExtensionsClientInputs() { Extensions = true, UserVerificationIndex = true, Location = true, UserVerificationMethod = true, BiometricAuthenticatorPerformanceBounds = new AuthenticatorBiometricPerfBounds { FAR = float.MaxValue, FRR = float.MaxValue } }; var options = _fido2.RequestNewCredential(user, existingKeys, authenticatorSelection, attType.ToEnum <AttestationConveyancePreference>(), exts); // 4. Temporarily store options, session/in-memory cache/redis/db HttpContext.Session.SetString("fido2.attestationOptions", options.ToJson()); // 5. return options to client return(Json(options)); } catch (Exception e) { return(Json(new CredentialCreateOptions { Status = "error", ErrorMessage = FormatException(e) })); } }
public IActionResult FindUser(string userName) { var user = _userStore.FindByUsername(userName); return(View(user)); }
public async Task <ReturnInfo <LoginReturnInfo> > Login(LoginInfo loginInfo) { // 这里写自定义登录验证 var context = await interactionService.GetAuthorizationContextAsync(loginInfo.ReturnUrl); var re = new ReturnInfo <LoginReturnInfo>() { Data = new LoginReturnInfo() { ReturnUrl = loginInfo.ReturnUrl } }; int num = HttpContext.Session.GetInt32("ErrLoginNum").GetValueOrDefault(); num++; //错误登录超过3次则需要验证码 if (num > 3) { if (string.IsNullOrWhiteSpace(loginInfo.VerificationCode)) { re.Data.IsVerificationCode = true; re.SetFailureMsg("请输入验证码"); return(re); } if (string.Compare(loginInfo.VerificationCode, HttpContext.Session.GetString("VerificationCode"), true) != 0) { re.Data.IsVerificationCode = true; re.SetFailureMsg("验证码不对,请输入正确的验证码"); return(re); } } if (users.ValidateCredentials(loginInfo.LoginId, loginInfo.Password)) { var user = users.FindByUsername(loginInfo.LoginId); var isuser = new IdentityServerUser(user.SubjectId) { DisplayName = user.Username, }; isuser.AdditionalClaims.Add(new Claim(ClaimTypes.Name, user.Username)); isuser.AdditionalClaims.Add(new Claim("ProviderName", user.ProviderName)); isuser.AdditionalClaims.Add(new Claim("ProviderSubjectId", user.ProviderSubjectId)); isuser.AdditionalClaims.Add(new Claim("c1", user.Claims.Where(p => p.Type == "c1").FirstOrDefault().Value)); re.SetSuccessMsg("登录成功"); HttpContext.Session.Remove("VerificationCode"); HttpContext.Session.Remove("ErrLoginNum"); await HttpContext.SignInAsync(isuser); } else { HttpContext.Session.SetInt32("ErrLoginNum", num); re.Data.IsVerificationCode = IsNeedIsVerificationCode(); re.SetFailureMsg("用户名或密码不对"); } return(re); }
// [ValidateAntiForgeryToken] public async Task <IActionResult> Login(object model1) { var type = typeof(LoginModel); var strr = model1.ToString(); var model = JsonConvert.DeserializeObject(strr, type) as LoginModel; // model.UserName = "******"; // model.Password = "******"; // model.Email = "*****@*****.**"; model.UserName = "******"; model.Password = "******"; model.Email = "*****@*****.**"; // model.ReturnUrl = "https://localhost:44308/authentication/login-callback"; // model.ReturnUrl = "https:\\localhost:5001/connect/authorize?client_id"; // check if we are in the context of an authorization request var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl); // // // the user clicked the "cancel" button // if (button != "login") { // if (context != null) { // // if the user cancels, send a result back into IdentityServer as if they // // denied the consent (even if this client does not require consent). // // this will send back an access denied OIDC error response to the client. // await _interaction.GrantConsentAsync(context, ConsentResponse.Denied); // // // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null // if (await _clientStore.IsPkceClientAsync(context.ClientId)) { // // if the client is PKCE then we assume it's native, so this change in how to // // return the response is for better UX for the end user. // return View("Redirect", new RedirectViewModel {RedirectUrl = model.ReturnUrl}); // } // // return Redirect(model.ReturnUrl); // } // else { // // since we don't have a valid context, then we just go back to the home page // return Redirect("~/"); // } // } if (ModelState.IsValid) { // validate username/password against in-memory store if (_users.ValidateCredentials(model.UserName, model.Password)) { var user = _users.FindByUsername(model.UserName); await _events.RaiseAsync(new UserLoginSuccessEvent(user.Username, user.SubjectId, user.Username, clientId : context?.ClientId)); // only set explicit expiration here if user chooses "remember me". // otherwise we rely upon expiration configured in cookie middleware. AuthenticationProperties props = null; props = new AuthenticationProperties { IsPersistent = true, ExpiresUtc = DateTimeOffset.UtcNow.Add(new TimeSpan(10, 10, 10, 10)) }; // issue authentication cookie with subject ID and username await HttpContext.SignInAsync(user.SubjectId, user.Username, props); var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, true, lockoutOnFailure : false); if (context != null) { // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null return(Ok(model.ReturnUrl)); } // request for a local page if (Url.IsLocalUrl(model.ReturnUrl)) { return(Ok(model.ReturnUrl)); } else if (string.IsNullOrEmpty(model.ReturnUrl)) { return(Ok()); } else { // user might have clicked on a malicious link - should be logged // throw new Exception("invalid return URL"); return(Ok(model.ReturnUrl)); } } await _events.RaiseAsync(new UserLoginFailureEvent(model.UserName, "invalid credentials", clientId : context?.ClientId)); // ModelState.AddModelError(string.Empty, AccountOptions.InvalidCredentialsErrorMessage); } // something went wrong, show form with error // var vm = await BuildLoginViewModelAsync(model); // return Ok(vm); return(Ok()); }
public async Task <IActionResult> Login(LoginInputModel model, string button) { // check if we are in the context of an authorization request var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl); // the user clicked the "cancel" button if (button != "login") { if (context != null) { // if the user cancels, send a result back into IdentityServer as if they // denied the consent (even if this client does not require consent). // this will send back an access denied OIDC error response to the client. await _interaction.DenyAuthorizationAsync(context, AuthorizationError.AccessDenied); // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null if (context.IsNativeClient()) { // The client is native, so this change in how to // return the response is for better UX for the end user. return(this.LoadingPage("Redirect", model.ReturnUrl)); } return(Redirect(model.ReturnUrl)); } else { // since we don't have a valid context, then we just go back to the home page return(Redirect("~/")); } } if (ModelState.IsValid) { // validate username/password against in-memory store if (_users.ValidateCredentials(model.Username, model.Password)) { var user = _users.FindByUsername(model.Username); await _events.RaiseAsync(new UserLoginSuccessEvent(user.Username, user.SubjectId, user.Username, clientId : context?.Client.ClientId)); // write a temp, encrypted cookie with values required for delegation. Cookie gets cleared on effective signin. var cookieModel = new // DelegationDataBag() { Subject = user.SubjectId, UserName = user.Username, ReturnUrl = model.ReturnUrl ?? "", RememberLogin = model.RememberLogin, IsNativeClient = context.IsNativeClient() }; var cookieDataInJson = JsonConvert.SerializeObject(cookieModel); var protectedData = _protector.Protect(cookieDataInJson); var options = new CookieOptions { Expires = DateTime.Now.AddMinutes(15) }; Response.Cookies.Append("DelegationDataBagCookie", protectedData, options); return(await ExecuteDelegationWhenApplicable( user.SubjectId, user.Username, model.ReturnUrl, model.RememberLogin, context.IsNativeClient())); // rest of code removed - is now handled after the delegation screen } await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, "invalid credentials", clientId : context?.Client.ClientId)); ModelState.AddModelError(string.Empty, AccountOptions.InvalidCredentialsErrorMessage); } // something went wrong, show form with error var vm = await BuildLoginViewModelAsync(model); return(View(vm)); }
public async Task <IActionResult> Index(LoginViewModel model) { //IdentityServer4.Validation.ScopeValidator if (!ModelState.IsValid) { ModelState.AddModelError(string.Empty, "账号密码必填"); return(View(model)); } if (!_users.ValidateCredentials(model.UserName, model.PassWord)) { ModelState.AddModelError(string.Empty, "账号密码错误"); return(View(model)); } //校验用户名、密码 if (_users.ValidateCredentials(model.UserName, model.PassWord)) { //获取用户实例 var user = _users.FindByUsername(model.UserName); //触发登陆成功事件 await _events.RaiseAsync(new UserLoginSuccessEvent(user.Username, user.SubjectId, user.Username)); AuthenticationProperties props = null; if (model.RememberLogin) //记住密码 { props = new AuthenticationProperties { IssuedUtc = DateTime.Now, ExpiresUtc = DateTime.Now.AddDays(1),//设置自动过期时间 AllowRefresh = false, IsPersistent = false, }; } // 登陆用户 保存到 cookie await HttpContext.SignInAsync(user.SubjectId, user.Username, props); // 获取授权上下文信息 var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl); if (context != null) { if (!string.IsNullOrWhiteSpace(context.ClientId)) { //查找登陆客户端 var _clientTemp = await _clientStore.FindEnabledClientByIdAsync(context.ClientId); if (_clientTemp?.RequirePkce == true) { // if the client is PKCE then we assume it's native, so this change in how to // return the response is for better UX for the end user. return(View("Redirect", new { RedirectUrl = model.ReturnUrl })); } // model.ReturnUrl 验证上下文成功 直接跳转 return(Redirect(model.ReturnUrl)); } } } return(Redirect(model.ReturnUrl ?? "/Home")); }
public async Task <IActionResult> Login(LoginInputModel model, string button) { //3: Enter credentials and click login // check if we are in the context of an authorization request var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl); // the user clicked the "cancel" button if (button != "login") { //it's cancel if (context != null) { // if the user cancels, send a result back into IdentityServer as if they // denied the consent (even if this client does not require consent). // this will send back an access denied OIDC error response to the client. await _interaction.GrantConsentAsync(context, ConsentResponse.Denied); return(Redirect(model.ReturnUrl)); } } if (ModelState.IsValid) { // validate username/password against in-memory store if (_users.ValidateCredentials(model.Username, model.Password)) { var user = _users.FindByUsername(model.Username); await _events.RaiseAsync(new UserLoginSuccessEvent(user.Username, user.SubjectId, user.Username)); // only set explicit expiration here if user chooses "remember me". // otherwise we rely upon expiration configured in cookie middleware. AuthenticationProperties props = null; if (AccountOptions.AllowRememberLogin && model.RememberLogin) { //remember login props = new AuthenticationProperties { IsPersistent = true, ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration) }; } ; // issue authentication cookie with subject ID and username await HttpContext.SignInAsync(user.SubjectId, user.Username, props); if (context != null) { // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null return(Redirect(model.ReturnUrl)); } } //bad credentials await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, "invalid credentials")); ModelState.AddModelError("", AccountOptions.InvalidCredentialsErrorMessage); } // something went wrong, show form with error (bad credentials) var vm = await BuildLoginViewModelAsync(model); return(View(vm)); }
public async Task <IActionResult> Login(LoginInputModel model, string button) { var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl); if (button != "login") { if (context != null) { await _interaction.GrantConsentAsync(context, ConsentResponse.Denied); if (await _clientStore.IsPkceClientAsync(context.ClientId)) { return(View("Redirect", new RedirectViewModel { RedirectUrl = model.ReturnUrl })); } return(Redirect(model.ReturnUrl)); } else { return(Redirect("~/")); } } if (ModelState.IsValid) { if (_users.ValidateCredentials(model.Username, model.Password)) { var user = _users.FindByUsername(model.Username); await _events.RaiseAsync(new UserLoginSuccessEvent(user.Username, user.SubjectId, user.Username)); AuthenticationProperties props = null; if (AccountOptions.AllowRememberLogin && model.RememberLogin) { props = new AuthenticationProperties { IsPersistent = true, ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration) }; } ; await HttpContext.SignInAsync(user.SubjectId, user.Username, props); if (context != null) { if (await _clientStore.IsPkceClientAsync(context.ClientId)) { return(View("Redirect", new RedirectViewModel { RedirectUrl = model.ReturnUrl })); } return(Redirect(model.ReturnUrl)); } if (Url.IsLocalUrl(model.ReturnUrl)) { return(Redirect(model.ReturnUrl)); } else if (string.IsNullOrEmpty(model.ReturnUrl)) { return(Redirect("~/")); } else { throw new Exception("invalid return URL"); } } await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, "invalid credentials")); ModelState.AddModelError(string.Empty, AccountOptions.InvalidCredentialsErrorMessage); } var vm = await BuildLoginViewModelAsync(model); return(View(vm)); }
public async Task <IActionResult> Login(LoginViewModel loginViewModel, string returnUrl) { if (ModelState.IsValid) { ViewData["ReturnUrl"] = returnUrl; var user = _users.FindByUsername(loginViewModel.UserName); if (user == null) { ModelState.AddModelError(nameof(loginViewModel.UserName), "UserName not exists"); } else { if (_users.ValidateCredentials(loginViewModel.UserName, loginViewModel.Password)) { var props = new AuthenticationProperties { IsPersistent = true, ExpiresUtc = DateTimeOffset.UtcNow.Add(TimeSpan.FromMinutes(30)) }; await Microsoft.AspNetCore.Http.AuthenticationManagerExtensions.SignInAsync( HttpContext, user.SubjectId, user.Username, props); return(RedirectToLoacl(returnUrl)); } ModelState.AddModelError(nameof(loginViewModel.Password), "Wrong Password"); } } //if (ModelState.IsValid) //{ // ViewData["ReturnUrl"] = returnUrl; // var user = await _userManager.FindByEmailAsync(loginViewModel.Email); // if (user == null) // { // ModelState.AddModelError(nameof(loginViewModel.Email), "Email not exists"); // } // else // { // if (await _userManager.CheckPasswordAsync(user, loginViewModel.Password)) // { // AuthenticationProperties props = null; // if (loginViewModel.RememberMe) // { // props = new AuthenticationProperties // { // IsPersistent = true, // ExpiresUtc = DateTimeOffset.UtcNow.Add(TimeSpan.FromMinutes(30)) // }; // } // await _signInManager.SignInAsync(user, props); // if (_identityServerInteractionService.IsValidReturnUrl(returnUrl)) // { // return Redirect(returnUrl); // } // return Redirect("~/"); // } // ModelState.AddModelError(nameof(loginViewModel.Password), "Wrong Password"); // } //} return(View(loginViewModel)); }
public async Task <IActionResult> Login(LoginViewModel model, string returnUrl = null) { //ViewData["ReturnUrl"] = returnUrl; //if (ModelState.IsValid) //{ // // This doesn't count login failures towards account lockout // // To enable password failures to trigger account lockout, set lockoutOnFailure: true // var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false); // if (result.Succeeded) // { // _logger.LogInformation("User logged in."); // return RedirectToLocal(returnUrl); // } // if (result.RequiresTwoFactor) // { // return RedirectToAction(nameof(LoginWith2fa), new { returnUrl, model.RememberMe }); // } // if (result.IsLockedOut) // { // _logger.LogWarning("User account locked out."); // return RedirectToAction(nameof(Lockout)); // } // else // { // ModelState.AddModelError(string.Empty, "Invalid login attempt."); // return View(model); // } //} // If we got this far, something failed, redisplay form //return View(model); if (ModelState.IsValid) { ViewData["returnUrl"] = returnUrl; var user = _users.FindByUsername(model.UserName); if (user == null) { ModelState.AddModelError(nameof(model.UserName), "UserName not exists"); } else { if (_users.ValidateCredentials(model.UserName, model.Password)) { //是否记住 var prop = new AuthenticationProperties() { IsPersistent = true, ExpiresUtc = DateTimeOffset.UtcNow.Add(TimeSpan.FromMinutes(30)) }; await Microsoft.AspNetCore.Http.AuthenticationManagerExtensions.SignInAsync(HttpContext, user.SubjectId, user.Username, prop); } } return(RedirectToLocal(returnUrl)); } return(View()); }