Example #1
0
        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));
        }
Example #3
0
        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"));
        }
Example #4
0
        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));
        }
Example #6
0
        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));
        }
Example #11
0
        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());
        }