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)); // 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")); 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(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(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) { bool suspicous = false; if (_loginBotDetection != null && await _loginBotDetection.IsSuspiciousUserAsync(model.Username)) { await _loginBotDetection.BlockSuspicousUser(model.Username); if (_captchaCodeRenderer != null) { if (!await _loginBotDetection.VerifyCaptchaCodeAsync(model.Username, model.CaptchaCode)) { suspicous = true; } } } var result = suspicous == true ? Microsoft.AspNetCore.Identity.SignInResult.Failed : await _signInManager.PasswordSignInAsync(model.Username, model.Password, model.RememberLogin, lockoutOnFailure : true); if (result.Succeeded) { var user = await _userManager.FindByNameAsync(model.Username); await _events.RaiseAsync(new UserLoginSuccessEvent(user.UserName, user.Id, 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) //{ // props = new AuthenticationProperties // { // IsPersistent = true, // ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration) // }; //}; // issue authentication cookie with subject ID and username //var isuser = new IdentityServerUser(user.SubjectId) //{ // DisplayName = user.Username //}; //await HttpContext.SignInAsync(isuser, props); if (_loginBotDetection != null) { await _loginBotDetection.RemoveSuspiciousUserAsync(model.Username); } 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(this.LoadingPage("Redirect", 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"); } } else if (result.RequiresTwoFactor) { if (_loginBotDetection != null) { await _loginBotDetection.RemoveSuspiciousUserAsync(model.Username); } string twoFactorUrl = "~/Identity/Account/LoginWith2fa?ReturnUrl={0}"; if (context != null || Url.IsLocalUrl(model.ReturnUrl)) { return(Redirect(string.Format(twoFactorUrl, HttpUtility.UrlEncode(model.ReturnUrl)))); } else { return(Redirect(string.Format(twoFactorUrl, HttpUtility.UrlEncode("~/")))); } } if (_loginBotDetection != null) { string captcaCode = await _loginBotDetection.AddSuspicousUserAndGenerateCaptchaCodeAsync(model.Username); if (await _loginBotDetection.IsSuspiciousUserAsync(model.Username)) { if (!String.IsNullOrEmpty(captcaCode) && _captchaCodeRenderer != null) { byte[] captchaImageBytes = _captchaCodeRenderer.RenderCodeToImage(captcaCode); model.CaptchaImage = captchaImageBytes; this.Response.Headers.Add("Content-Security-Policy", "default-src 'self' data:; object-src 'none'; frame-ancestors 'none'; sandbox allow-forms allow-same-origin allow-scripts; base-uri 'self';"); } } } 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(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) { HttpClient client = _httpClientFactory.CreateClient(); var disco = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest { Address = Configuration["IdentityService:Authority"], Policy = { RequireHttps = false } }); if (disco.IsError) { throw new Exception(disco.Error); } var tokenResponse = await client.RequestPasswordTokenAsync(new PasswordTokenRequest { Address = disco.TokenEndpoint, ClientId = "GeneralApiClient", ClientSecret = "P@ssw0rd", UserName = model.Username, Password = model.Password, Scope = "GeneralServiceApi offline_access" }); if (!tokenResponse.IsError) { await _events.RaiseAsync(new UserLoginSuccessEvent("", model.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) { props = new AuthenticationProperties { IsPersistent = true, ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration) }; } ; Claim accessTokenClaim = new Claim("general_access_token", tokenResponse.AccessToken); Claim refreshTokenClaim = new Claim("general_refresh_token", tokenResponse.RefreshToken); List <Claim> listClaim = new List <Claim>() { accessTokenClaim, refreshTokenClaim }; // issue authentication cookie with subject ID and username await HttpContext.SignInAsync(model.Username, props, listClaim.ToArray()); 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"); } } else { await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, "invalid credentials")); string errMsg = tokenResponse.Error + ":" + (string.IsNullOrEmpty(tokenResponse.ErrorDescription) ? "" : tokenResponse.ErrorDescription); ModelState.AddModelError(string.Empty, errMsg); } } // something went wrong, show form with error var vm = await 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) { var result = await _signInManager.PasswordSignInAsync(model.Username, model.Password, model.RememberLogin, lockoutOnFailure : true); if (result.Succeeded) { var user = await _userManager.FindByNameAsync(model.Username); await _events.RaiseAsync(new UserLoginSuccessEvent(user.UserName, user.Id, user.UserName)); 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")); 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(LoginInputModel model, string button) { // 检查我们是否在授权请求的上下文中 var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl); // 用户单击“取消”按钮 if (button != "login") { if (context != null) { //如果用户取消,则将结果发送到身份服务器,就像 // 拒绝同意(即使该客户不需要同意)。 // 这将向客户端发回一个被拒绝的oidc错误响应。 await _interaction.GrantConsentAsync(context, ConsentResponse.Denied); // 我们可以信任模特。因为GetAuthorizationContextAsync回来了 if (await _clientStore.IsPkceClientAsync(context.ClientId)) { // 如果客户端是pkce,那么我们假设它是本地的,因此在如何 // 返回响应是为了最终用户获得更好的ux。 return(View("Redirect", new RedirectViewModel { RedirectUrl = model.ReturnUrl })); } return(Redirect(model.ReturnUrl)); } else { // 既然我们没有一个有效的上下文,那么我们就回到主页 return(Redirect("~/")); } } if (ModelState.IsValid) { //查找用户 //var user = _userApp.GetUser(model.Username); var requestUri = "http://localhost:61927/api/Account"; var response = MyHttp.Post(requestUri, null, model); CJ.Models.LoginInputModel user = new CJ.Models.LoginInputModel(); if (!string.IsNullOrEmpty(response.Data)) { user = JsonConvert.DeserializeObject <CJ.Models.LoginInputModel>(response.Data); } else { user = null; }; //对内存中的用户名/密码进行验证 if (user != null && (model.Password == DESCrypt.Decrypt(user.Password))) { await _events.RaiseAsync(new UserLoginSuccessEvent(user.Username, user.Id, user.Username)); // 如果用户选择“记住我”,只在此设置显式过期。 // 否则,我们将依赖于Cookie中间件中配置的过期。 AuthenticationProperties props = null; if (AccountOptions.AllowRememberLogin && model.RememberLogin) { props = new AuthenticationProperties { IsPersistent = true, //认证信息是否跨域有效 ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration) //凭据有效时间 }; } ; var serverUser = new IdentityServerUser(user.Id); serverUser.DisplayName = user.DisplayName; var claims = new[] { new Claim("Username", user.Username), new Claim("DisplayName", user.DisplayName) }; serverUser.AdditionalClaims = claims; // issue authentication cookie with subject ID and username await HttpContext.SignInAsync(serverUser); if (context != null) { if (await _clientStore.IsPkceClientAsync(context.ClientId)) { // 如果客户端是pkce,那么我们假设它是本地的,所以在如何 // 返回的响应是为最终用户提供更好的ux。 return(View("Redirect", new RedirectViewModel { RedirectUrl = model.ReturnUrl })); } // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null 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("无效的返回URL"); } } await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, "无效的凭据")); ModelState.AddModelError(string.Empty, AccountOptions.InvalidCredentialsErrorMessage); } // 出了问题,显示形式错误 var vm = await BuildLoginViewModelAsync(model); return(View(vm)); }