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)); // 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 }; 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)); // rest of code removed - is now handled after the delegation screen } 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> Callback() { // read external identity from the temporary cookie var result = await HttpContext.AuthenticateAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme); if (result?.Succeeded != true) { throw new Exception("External authentication error"); } if (_logger.IsEnabled(LogLevel.Debug)) { var externalClaims = result.Principal.Claims.Select(c => $"{c.Type}: {c.Value}"); _logger.LogDebug("External claims: {@claims}", externalClaims); } BaseAuthProvider authProvider = ProviderFactory.CreateProvider(result); var subject = authProvider.GetSubject(); if (string.IsNullOrEmpty(subject)) { throw new Exception("External authentication error"); } // lookup our user and external provider info var(user, provider, providerUserId, claims) = await FindUserFromExternalProvider(result, subject); if (user == null) { string email = authProvider.GetEmail(); var fullName = result.Principal.Identity.Name; user = await _userService.RegisterUserAsync(new UserDto { FullName = fullName, Position = "", Email = email, RoleId = (int)Roles.Spectator, ExternalId = subject }); } // this allows us to collect any additional claims or properties // for the specific protocols used and store them in the local auth cookie. // this is typically used to store data needed for signout from those protocols. var additionalLocalClaims = new List <Claim>(); var localSignInProps = new AuthenticationProperties(); ProcessLoginCallbackForOidc(result, additionalLocalClaims, localSignInProps, user); // issue authentication cookie for user var isuser = new IdentityServerUser(subject) { DisplayName = user.FullName, IdentityProvider = provider, AdditionalClaims = additionalLocalClaims, }; await HttpContext.SignInAsync(isuser, localSignInProps); // delete temporary cookie used during external authentication await HttpContext.SignOutAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme); // retrieve return URL var returnUrl = result.Properties.Items["returnUrl"] ?? "~/"; // check if external login is in the context of an OIDC request var context = await _interaction.GetAuthorizationContextAsync(returnUrl); await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, subject, user.FullName, true, context?.ClientId)); 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", returnUrl)); } } return(Redirect(returnUrl)); }
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, clientId : context?.ClientId)); 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> Callback() { // read external identity from the temporary cookie var result = await HttpContext.AuthenticateAsync( IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme); if (result?.Succeeded != true) { throw new Exception("External authentication error"); } if (_logger.IsEnabled(LogLevel.Debug)) { var externalClaims = result.Principal.Claims.Select(c => $"{c.Type}: {c.Value}"); _logger.LogDebug("External claims: {@claims}", externalClaims); } // lookup our user and external provider info var(user, provider, providerUserId, claims) = await FindUserFromExternalProvider(result); if (user == null) { // this might be where you might initiate a custom workflow for user registration // in this sample we don't show how that would be done, as our sample implementation // simply auto-provisions new external user if (provider == "Facebook") { // redirect to the RegisterUserFromFacebook view. return(RedirectToAction( "RegisterUserFromFacebook", "UserRegistration", new RegisterUserFromFacebookInputViewModel() { Email = claims.FirstOrDefault(c => c.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress")?.Value, GivenName = claims.FirstOrDefault(c => c.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname")?.Value, FamilyName = claims.FirstOrDefault(c => c.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname")?.Value, Provider = provider, ProviderUserId = providerUserId })); } else { user = await AutoProvisionWindowsUser(provider, providerUserId, claims); } } // this allows us to collect any additonal claims or properties // for the specific prtotocols used and store them in the local auth cookie. // this is typically used to store data needed for signout from those protocols. var additionalLocalClaims = new List <Claim>(); var localSignInProps = new AuthenticationProperties(); ProcessLoginCallbackForOidc(result, additionalLocalClaims, localSignInProps); ProcessLoginCallbackForWsFed(result, additionalLocalClaims, localSignInProps); ProcessLoginCallbackForSaml2p(result, additionalLocalClaims, localSignInProps); // issue authentication cookie for user await HttpContext.SignInAsync(user.Subject, user.Username, provider, localSignInProps, additionalLocalClaims.ToArray()); // delete temporary cookie used during external authentication await HttpContext.SignOutAsync( IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme); // retrieve return URL var returnUrl = result.Properties.Items["returnUrl"] ?? "~/"; // check if external login is in the context of an OIDC request var context = await _interaction.GetAuthorizationContextAsync(returnUrl); await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.Subject, user.Username, true, context?.ClientId)); 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 = returnUrl })); } } return(Redirect(returnUrl)); }
public async Task <IActionResult> Callback() { // read external identity from the temporary cookie var result = await HttpContext.AuthenticateAsync(IdentityConstants.ExternalScheme); if (result?.Succeeded != true) { throw new Exception("External authentication error"); } var externalUser = result.Principal; var claims = externalUser.Claims.ToList(); var userIdClaim = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Subject); if (userIdClaim == null) { userIdClaim = claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier); } if (userIdClaim == null) { throw new Exception("Unknown userid"); } claims.Remove(userIdClaim); if (_logger.IsEnabled(LogLevel.Debug)) { var externalClaims = result.Principal.Claims.Select(c => $"{c.Type}: {c.Value}"); _logger.LogDebug("External claims: {@claims}", externalClaims); } var provider = result.Properties.Items["scheme"]; var userId = userIdClaim.Value; var user = await _userManager.FindByLoginAsync(provider, userId); if (user == null) { user = new IdentityUser { UserName = Guid.NewGuid().ToString() }; await _userManager.CreateAsync(user); await _userManager.AddLoginAsync(user, new UserLoginInfo(provider, userId, provider)); } // this allows us to collect any additonal claims or properties // for the specific prtotocols used and store them in the local auth cookie. // this is typically used to store data needed for signout from those protocols. var additionalLocalClaims = new List <Claim>(); var localSignInProps = new AuthenticationProperties(); ProcessLoginCallbackForOidc(result, additionalLocalClaims, localSignInProps); ProcessLoginCallbackForWsFed(result, additionalLocalClaims, localSignInProps); ProcessLoginCallbackForSaml2p(result, additionalLocalClaims, localSignInProps); // issue authentication cookie for user await HttpContext.SignInAsync(user.Id, user.UserName, provider, localSignInProps, additionalLocalClaims.ToArray()); // delete temporary cookie used during external authentication await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme); // retrieve return URL var returnUrl = result.Properties.Items["returnUrl"] ?? "~/"; // check if external login is in the context of an OIDC request var context = await _interaction.GetAuthorizationContextAsync(returnUrl); await _events.RaiseAsync(new UserLoginSuccessEvent(provider, userIdClaim.Value, user.Id, user.UserName, true, context?.ClientId)); 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 = returnUrl })); } } return(Redirect(returnUrl)); }
public async Task <IActionResult> Login(LoginInputModel model, string button) { // the user clicked the "cancel" button if (button != "login") { return(await CancelTokenRequest(model.ReturnUrl)); } if (ModelState.IsValid) { // check if we are in the context of an authorization request var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl); var result = await _signInManager.PasswordSignInAsync(model.Username, model.Password, model.RememberLogin, lockoutOnFailure : true); if (result.RequiresTwoFactor) { return(await RedirectTo2FA(model.ReturnUrl, model.Username)); } if (result.Succeeded) { var user = await _userManager.FindByNameAsync(model.Username); // Redirect to 2fa offer screen if any options are available if (TwoFACompulsary()) { if (context != null) { await _interaction.GrantConsentAsync(context, ConsentResponse.Denied); } return(RedirectToAction("Register2FA", new { redirectUrl = model.ReturnUrl })); } // Redirect to 2fa offer screen if any options are available if (Any2FAEnabled()) { return(RedirectToAction("LoginSuccessful", new { redirectUrl = model.ReturnUrl, show2FARegMessage = true })); } 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"); } } else { if (result.IsLockedOut) { await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, "account locked out")); ModelState.AddModelError(string.Empty, AccountOptions.AccountLockedOutErrorMessage); } else { 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> Callback() { // read external identity from the temporary cookie var result = await HttpContext.AuthenticateAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme); if (result?.Succeeded != true) { throw new Exception("External authentication error"); } var extPrincipal = result.Principal; var expProperties = result.Properties; var claims = extPrincipal.Claims.ToList(); var userIdClaim = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Subject); if (userIdClaim == null) { userIdClaim = claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier); } if (userIdClaim == null) { throw new Exception("Unknown userid"); } claims.Remove(userIdClaim); var provider = expProperties.Items["scheme"]; var userId = userIdClaim.Value; var user = await _userManager.FindByLoginAsync(provider, userId); if (user == null) { var candidateId = Guid.NewGuid(); user = new ApplicationUser(); var emailClaim = claims.FirstOrDefault(x => x.Type == ClaimTypes.Email); if (emailClaim != null) { user.UserName = emailClaim.Value; user.Email = emailClaim.Value; user.EmailConfirmed = true; } var firstNameClaim = claims.FirstOrDefault(x => x.Type == ClaimTypes.GivenName); if (firstNameClaim != null) { user.FirstName = firstNameClaim.Value; } var lastNameClaim = claims.FirstOrDefault(x => x.Type == ClaimTypes.Surname); if (lastNameClaim != null) { user.LastName = lastNameClaim.Value; } user.UserType = EnumUserType.Audience; var createResult = await _userManager.CreateAsync(user); if (createResult.Succeeded) { var loginResult = await _userManager.AddLoginAsync(user, new UserLoginInfo(provider, userId, provider)); if (loginResult.Succeeded) { // Update Tokens to AspNet Identity var externalLoginInfo = new ExternalLoginInfo(extPrincipal, provider, userId, provider) { AuthenticationTokens = expProperties.GetTokens() }; await _signInManager.UpdateExternalAuthenticationTokensAsync(externalLoginInfo); } } } // this allows us to collect any additonal claims or properties // for the specific prtotocols used and store them in the local auth cookie. // this is typically used to store data needed for signout from those protocols. var additionalLocalClaims = new List <Claim>(); var localSignInProps = new AuthenticationProperties(); ProcessLoginCallbackForOidc(result, additionalLocalClaims, localSignInProps); ProcessLoginCallbackForWsFed(result, additionalLocalClaims, localSignInProps); ProcessLoginCallbackForSaml2p(result, additionalLocalClaims, localSignInProps); // issue authentication cookie for user await _events.RaiseAsync(new UserLoginSuccessEvent(provider, userId, user.Id, user.UserName)); await HttpContext.SignInAsync( user.Id, user.UserName, provider, localSignInProps, additionalLocalClaims.ToArray() ); // delete temporary cookie used during external authentication await HttpContext.SignOutAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme); // retrieve return URL var returnUrl = result.Properties.Items["returnUrl"] ?? "~/"; // check if external login is in the context of an OIDC request var context = await _interaction.GetAuthorizationContextAsync(returnUrl); 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 = returnUrl })); } } return(Redirect(returnUrl)); }
public async Task <IActionResult> Callback() { // read external identity from the temporary cookie var result = await HttpContext.AuthenticateAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme); if (result?.Succeeded != true) { throw new Exception("External authentication error"); } var externalUser = result.Principal; // try to determine the unique id of the external user (issued by the provider) // the most common claim type for that are the sub claim and the NameIdentifier // depending on the external provider, some other claim type might be used var userIdClaim = externalUser.FindFirst(JwtClaimTypes.Subject) ?? externalUser.FindFirst(ClaimTypes.NameIdentifier) ?? throw new Exception("Unknown userid"); // this allows us to collect any additonal claims or properties // for the specific prtotocols used and store them in the local auth cookie. // this is typically used to store data needed for signout from those protocols. var additionalLocalClaims = new List <Claim>(); var localSignInProps = new AuthenticationProperties(); var googleData = ProcessLoginCallbackForOidc(result, additionalLocalClaims, localSignInProps); // remove the user id claim so we don't include it as an extra claim if/when we provision the user var claims = externalUser.Claims.ToList(); claims.Remove(userIdClaim); var provider = result.Properties.Items["scheme"]; var providerUserId = userIdClaim.Value; // find external user //var user = _users.FindByExternalProvider(provider, providerUserId); var user = _context.Users.FirstOrDefault(f => f.NameIdentifier == providerUserId); //user doesnt exist so we want to add him/her if (user == null) { user = new AppUser() { Email = googleData.Email, FirstName = googleData.FirstName, LastName = googleData.Surname, Id = DateTime.Now.Ticks.ToString(), NameIdentifier = googleData.NameIdentifier, UserName = googleData.Name, PictureUrl = googleData.Image }; _context.Users.Add(user); _context.SaveChanges(); } var token = new Token() { Expires = googleData.Expires, Issued = googleData.Issued, Name = googleData.TokenName, UserId = user.Id, Provider = provider, Type = googleData.TokenType, Value = googleData.AccessToken, Refresh = googleData.Refresh, ImageUrl = googleData.Image, Locale = googleData.Locale }; _context.Tokens.Add(token); _context.SaveChanges(); // issue authentication cookie for user await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.Id, user.UserName)); await HttpContext.SignInAsync(user.NameIdentifier, user.UserName, provider, localSignInProps, additionalLocalClaims.ToArray()); // delete temporary cookie used during external authentication await HttpContext.SignOutAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme); // retrieve return URL var returnUrl = result.Properties.Items["returnUrl"] ?? "~/"; // check if external login is in the context of an OIDC request var context = await _interaction.GetAuthorizationContextAsync(returnUrl); 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. Debug.WriteLine("ret url : " + returnUrl); return(View("Redirect", new RedirectViewModel { RedirectUrl = returnUrl })); } } Debug.WriteLine("ret url : " + returnUrl); return(Redirect(returnUrl)); }
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); var redirectDomain = HelperUrl.GetRedirectDomain(model.ReturnUrl); var ReturnUrl = HelperUrl.GetRedirectUrl(model.ReturnUrl); var clientId = HelperUrl.GetClientId(model.ReturnUrl); if (ModelState.IsValid) { model.RememberLogin = true; // validate username/password against in-memory store var user = await _usersServices.Auth(model.Username, model.Password); if (user.IsNull()) { await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, "invalid credentials")); ModelState.AddModelError("", AccountOptions.InvalidCredentialsErrorMessage); } else if (user.Error.IsNotNullOrEmpty()) { await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, "invalid credentials")); ModelState.AddModelError("", user.Error); } else { if (user.ChangePassword) { model.ReturnUrl = "/ChangePassword?ReturnUrl=" + ReturnUrl; } 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, user.Claims.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"); } } } // 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 // unutar ovog projekta u Config.cs postavljen je RedirectUri // GetAuthorizedContext provjerava da li je returnUri s kojeg je dosao request unutar jedan od onih unutar Configa.cs // Ovo sprecava druge ljude da rucno odu na nas localhost:5000/Account/Login i da dobiju pristup var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl); // the user clicked the "cancel" button // ovaj citav IF je jeben za skontat, al nece se nama ovo desavat // i da se desi postavljeno je ovo sve defaultno od Identity Servera da ih vraca odakle su dosli 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("~/")); } } // Ova if petlja ako je izvor uredu i ako nema gresaka validacijskih unutar ViewModela if (ModelState.IsValid) { // Ova funkcija je bukvalno za login od strane Microsoft Identitya var result = await _signInManager.PasswordSignInAsync(model.Username, model.Password, model.RememberLogin, lockoutOnFailure : true); if (result.Succeeded) { // Microsoft Identity funkcija koja vraca ApplicationUser objekat lika koji se ulogovao var user = await _userManager.FindByNameAsync(model.Username); //Ovo je od Identity Servera 4 da ga obavjestimo da je User uspjesno logovan i da mu da Token ili Cookies ili sta vec await _events.RaiseAsync(new UserLoginSuccessEvent(user.UserName, user.Id, user.UserName, clientId : context?.ClientId)); //Ista provjera ko gora na prvom velikom ifu // Provjeravamo da li je request pravi, validan if (context != null) { // Kod nas nece bit PKCE klijenata ovdje nece nikad uci 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 // Uspjesno smo loginovali korisnika, dali mu Access Token i mozemo ga redirectat na Festival return(Redirect(model.ReturnUrl)); } // request for a local page // ovo je ako je los autorizaciji request tj. ako je context == null // vracamo ga odakle je dosao if (Url.IsLocalUrl(model.ReturnUrl)) { return(Redirect(model.ReturnUrl)); } // Ako user nema return url vracamo ga na pocetnu stranicu nasu // u ovom slucaju pocetnu od identity servera else if (string.IsNullOrEmpty(model.ReturnUrl)) { var roles = await _userManager.GetRolesAsync(user); if (roles.Contains("Admin")) { return(Redirect("https://127.0.0.1:44330/Admin")); } else { return(Redirect("https://127.0.0.1:44330/")); } } // ako skripta, bot ili slicno pokusaju nam loginovat throwa exception else { // user might have clicked on a malicious link - should be logged throw new Exception("invalid return URL"); } } // Ako malo bolje se zagledas ovo je bukvalno Else od onog gore Result.Succeded tj ako je pogresne kredencijale ukucao 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 // Vracamo ga na nas Login View gdje mu izbacujemo Invalid username or passowrd // Pokusaj jednom pogresno ukucat i vidjeces da ce ti ovaj dio bacit 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) }; } ; GeneralApiToken generalApiToken = new GeneralApiToken() { ExpiresAt = DateTime.UtcNow.AddSeconds(tokenResponse.ExpiresIn), AccessToken = tokenResponse.AccessToken, RefreshToken = tokenResponse.RefreshToken }; Claim tokenClaim = new Claim("general_api_token", JsonConvert.SerializeObject(generalApiToken)); List <Claim> listClaim = new List <Claim>() { tokenClaim }; // 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> Callback() { // read external identity from the temporary cookie var result = await HttpContext.AuthenticateAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme); if (result?.Succeeded != true) { throw new Exception("External authentication error"); } var externalUser = result.Principal; string FullName = externalUser.FindFirst(ClaimTypes.Name)?.Value ?? " "; string GivenName = externalUser.FindFirst(ClaimTypes.GivenName)?.Value ?? " "; string Surname = externalUser.FindFirst(ClaimTypes.Surname)?.Value ?? " "; string Email = externalUser.FindFirst(ClaimTypes.Email)?.Value; // lookup our user and external provider info var(user, provider, providerUserId, claims) = FindUserFromExternalProvider(result); if (user == null) { var newUser = new User { Name = GivenName, Username = Email, Password = "", Profile = "Everyone", Email = Email, Provider = provider, UserProviderId = providerUserId }; _userRepository.Add(newUser); user = newUser; } else { user.UserProviderId = providerUserId; user.Provider = provider; _userRepository.Update(user); _userRepository.Save(); } // this allows us to collect any additonal claims or properties // for the specific prtotocols used and store them in the local auth cookie. // this is typically used to store data needed for signout from those protocols. var additionalLocalClaims = new List <Claim>(); var localSignInProps = new AuthenticationProperties(); ProcessLoginCallbackForOidc(result, additionalLocalClaims, localSignInProps); ProcessLoginCallbackForWsFed(result, additionalLocalClaims, localSignInProps); ProcessLoginCallbackForSaml2p(result, additionalLocalClaims, localSignInProps); // issue authentication cookie for user await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.UsersId.ToString(), user.Username)); var isuser = new IdentityServerUser(user.UsersId.ToString()) { DisplayName = user.Username, IdentityProvider = provider, AdditionalClaims = additionalLocalClaims }; await HttpContext.SignInAsync(isuser, localSignInProps); // delete temporary cookie used during external authentication await HttpContext.SignOutAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme); // retrieve return URL var returnUrl = result.Properties.Items["returnUrl"] ?? "~/"; // check if external login is in the context of an OIDC request var context = await _interaction.GetAuthorizationContextAsync(returnUrl); if (context != null) { if (await _clientStore.IsPkceClientAsync(context.Client.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 = returnUrl })); } } return(Redirect(returnUrl)); }
public async Task <IActionResult> Login(LoginInputModel model, string button) { // check if we are in the context of an authorization request AuthorizationRequest 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) { DiscoveryResponse disco = await DiscoveryClient.GetAsync("http://localhost:5000"); TokenClient tokenClient = new TokenClient(disco.TokenEndpoint, "MvcServer", "secret"); var tokenResponse = await tokenClient.RequestClientCredentialsAsync("api1"); var client = new HttpClient(); client.SetBearerToken(tokenResponse.AccessToken); try { var response = await client.GetAsync("http://localhost:5001/api/values/" + model.Username + "/" + model.Password); if (!response.IsSuccessStatusCode) { throw new Exception("Resource server is not working!"); } else { var content = await response.Content.ReadAsStringAsync(); User user = JsonConvert.DeserializeObject <User>(content); if (user != null) { await _events.RaiseAsync(new UserLoginSuccessEvent(user.UserName, user.UserId, 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) }; } ; // context.Result = new GrantValidationResult( //user.SubjectId ?? throw new ArgumentException("Subject ID not set", nameof(user.SubjectId)), //OidcConstants.AuthenticationMethods.Password, _clock.UtcNow.UtcDateTime, //user.Claims); // issue authentication cookie with subject ID and username await HttpContext.SignInAsync(user.UserId, 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("", AccountOptions.InvalidCredentialsErrorMessage); } } catch (Exception ex) { await _events.RaiseAsync(new UserLoginFailureEvent("Resource server", "is not working!")); ModelState.AddModelError("", "Resource server is not working"); } } // 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. //如果用户取消,则将结果发送回IdentityServer,如同他们拒绝同意一样(即使此客户端不需要同意)。 //这将向客户端发送拒绝访问的OIDC错误响应。 await _interaction.GrantConsentAsync(context, ConsentResponse.Denied); // we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null //我们可以信任Model.ReturnURL,因为GetAuthorizationContextAsync返回非空值 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. //如果客户机是pkce,那么我们假设它是本机的,所以如何返回响应的这种更改是为了更好地为最终用户提供UX。 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"); * } * } */ var user = _userDbContext.Users.Where(x => x.Name == model.Username && x.Password == model.Password).FirstOrDefault(); if (user != null) { //var user = _users.FindByUsername(model.Username); // RaiseAsync 引发指定的事件。 // 引发用户登录成功的事件 await _events.RaiseAsync(new UserLoginSuccessEvent(user.Name, user.Id.ToString(), user.Name)); // only set explicit expiration here if user chooses "remember me". // otherwise we rely upon expiration configured in cookie middleware. //仅当用户选择“记住我”时才在此处设置显式过期。 //否则,我们依赖于在cookie中间件中配置的过期。 AuthenticationProperties props = null; // 用于存储有关身份验证会话的状态值的字典 //记住登录 if (AccountOptions.AllowRememberLogin && model.RememberLogin) { props = new AuthenticationProperties { IsPersistent = true,//获取或设置是否跨多个请求持久化身份验证会话 //获取或设置身份验证票证过期的时间。 默认30天? ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration) }; } ; // issue authentication cookie with subject ID and username //颁发具有使用者ID和用户名的身份验证cookie await HttpContext.SignInAsync(user.Id.ToString(), user.Name, 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> Callback() { // read external identity from the temporary cookie var result = await HttpContext.AuthenticateAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme); if (result?.Succeeded != true) { throw new Exception("External authentication error"); } var retrnurl = result.Properties.Items["returnUrl"]; // lookup our user and external provider info var(user, provider, providerUserId, claims) = await FindUserFromExternalProviderAsync(result); if (user == null) { // this might be where you might initiate a custom workflow for user registration // in this sample we don't show how that would be done, as our sample implementation // simply auto-provisions new external user //user = _userManager.FindByEmailAsync(claim) var email = claims.FirstOrDefault(x => x.Value.Contains("@"))?.Value; if (!string.IsNullOrWhiteSpace(email)) { var tentativeUser = await _userManager.FindByEmailAsync(email); if (tentativeUser != null) { //var retrnurl = result.Properties.Items["returnUrl"]; var m = new ExternalLoginAssociationViewModel { Email = email, Provider = provider, ProviderKey = providerUserId, ProviderDisplayName = provider, ReturnUrl = retrnurl }; return(View("ExternalLoginAssociation", m)); } } else { email = "None"; } //await HttpContext.SignOutAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme); return(View("ExternalLoginFailure", new ExternalLoginFailureViewModel { Email = email, RedirectUri = retrnurl, ClientName = "" })); //RedirectToAction(nameof(AccountController.Login)); //user = AutoProvisionUser(provider, providerUserId, claims); //return RedirectToAction(nameof(AccountController.Login)); } // this allows us to collect any additonal claims or properties // for the specific prtotocols used and store them in the local auth cookie. // this is typically used to store data needed for signout from those protocols. var additionalLocalClaims = new List <Claim>(); var localSignInProps = new AuthenticationProperties() { IsPersistent = true, ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.ExternalProviderLoginDurationOverride) }; ProcessLoginCallbackForOidc(result, additionalLocalClaims, localSignInProps); ProcessLoginCallbackForWsFed(result, additionalLocalClaims, localSignInProps); ProcessLoginCallbackForSaml2p(result, additionalLocalClaims, localSignInProps); // issue authentication cookie for user await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.Id, user.UserName)); await _signInManager.SignInAsync(user, localSignInProps, provider); //await HttpContext.SignInAsync(user.Id, user.UserName, provider, localSignInProps, additionalLocalClaims.ToArray()); // delete temporary cookie used during external authentication await HttpContext.SignOutAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme); // retrieve return URL var returnUrl = result.Properties.Items["returnUrl"] ?? "~/"; // check if external login is in the context of an OIDC request var context = await _interaction.GetAuthorizationContextAsync(returnUrl); 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 = returnUrl })); } } return(Redirect(returnUrl)); }
public async Task <IActionResult> Callback() { var result = await HttpContext.AuthenticateAsync( IdentityServerConstants.ExternalCookieAuthenticationScheme ); if (false == result?.Succeeded) { logger.LogError($"[ExternalController.Callback] {result.Failure}"); throw result.Failure ?? new Exception(); } var(user, provider, providerUserId, claims) = await FindCustomerFromExternalProviderAsync(result); if (null == user) { //user = await AutoProvisionCustomerAsync(provider, providerUserId, claims); return(await AutoProvisionCustomerAsync(provider, providerUserId, claims)); } var localClaims = new List <Claim>(); var localProperties = new AuthenticationProperties(); ProcessLoginCallbackForOidc(result, localClaims, localProperties); //ProcessLoginCallbackForWsFed(result, localClaims, localProperties); //ProcessLoginCallbackForSaml2p(result, localClaims, localProperties); // issue authentication cookie for user await eventService.RaiseAsync(new UserLoginSuccessEvent( provider, providerUserId, user.Id.ToString(), user.UserName) ); var signin = await signInManager.ExternalLoginSignInAsync(provider, providerUserId, true); if (false == signin.Succeeded) { return(BadRequest()); } // delete temporary cookie used during external authentication await HttpContext.SignOutAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme); // retrieve return URL var returnUrl = result.Properties.Items["returnUrl"] ?? "~/"; // check if external login is in the context of an OIDC request var context = await interaction.GetAuthorizationContextAsync(returnUrl); if (null != context) { 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 RedirectModel { RedirectUrl = returnUrl })); } } return(Redirect(returnUrl)); }
public async Task <IActionResult> Callback() { // read external identity from the temporary cookie var result = await HttpContext.AuthenticateAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme); if (result?.Succeeded != true) { throw new Exception("External authentication error"); } if (_logger.IsEnabled(LogLevel.Debug)) { var externalClaims = result.Principal.Claims.Select(c => $"{c.Type}: {c.Value}"); _logger.LogDebug("External claims: {@claims}", externalClaims); } // lookup our user and external provider info var(user, provider, providerUserId, claims) = await FindUserFromExternalProvider(result); if (user == null) { // Aqui se podría empezar un flow de registro para indicar campos para registrar el usuario // Por ahora se crea el usuario con la información básica usando los claims recibidos user = await AutoProvisionUser(provider, providerUserId, claims); } // this allows us to collect any additonal claims or properties for the specific // prtotocols used and store them in the local auth cookie. this is typically used to // store data needed for signout from those protocols. var additionalLocalClaims = new List <Claim>(); var localSignInProps = new AuthenticationProperties(); ProcessLoginCallbackForOidc(result, additionalLocalClaims, localSignInProps); ProcessLoginCallbackForWsFed(result, additionalLocalClaims, localSignInProps); ProcessLoginCallbackForSaml2p(result, additionalLocalClaims, localSignInProps); // issue authentication cookie for user await HttpContext.SignInAsync(user.Id.ToString(), user.UserName, provider, localSignInProps, additionalLocalClaims.ToArray()); // delete temporary cookie used during external authentication await HttpContext.SignOutAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme); // retrieve return URL var returnUrl = result.Properties.Items["returnUrl"] ?? "~/"; // check if external login is in the context of an OIDC request var context = await _interaction.GetAuthorizationContextAsync(returnUrl); await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.Id.ToString(), user.UserName, true, context?.ClientId)); 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 = returnUrl })); } } return(Redirect(returnUrl)); }
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); ApplicationUser user = await GetUserByUsernameOrEmail(model.Username); if (user == null || user.PasswordHash == null) { await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, "invalid credentials")); ModelState.AddModelError("", AccountOptions.InvalidCredentialsErrorMessage); var vm1 = await BuildLoginViewModelAsync(model); return(View(vm1)); } var isLockedOut = await _userManager.IsLockedOutAsync(user); if (isLockedOut) { await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, "user is locked out")); ModelState.AddModelError("", AccountOptions.InvalidCredentialsErrorMessage); var vm1 = await BuildLoginViewModelAsync(model); return(View(vm1)); } var result = _userManager.PasswordHasher.VerifyHashedPassword(user, user.PasswordHash, model.Password); //if (result.Succeeded) //{ if (result != PasswordVerificationResult.Failed) //result is either Success or SuccessRehashNeeded { //var user = await _userManager.FindByNameAsync(model.Username); await _events.RaiseAsync(new UserLoginSuccessEvent(user.UserName, user.Id, user.UserName)); if (result == PasswordVerificationResult.SuccessRehashNeeded) { //update passwordHash from old to new encryption user.PasswordHash = _userManager.PasswordHasher.HashPassword(user, model.Password); } user.AccessFailedCount = 0; await _userManager.UpdateAsync(user); AuthenticationProperties props = null; if (AccountOptions.AllowRememberLogin && model.RememberLogin) { props = new AuthenticationProperties { IsPersistent = true, ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration) }; } ; await _signInManager.SignInAsync(user, 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("", 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) { var user = await _loginService.FindByUsername(model.Username); bool rememberMe = AccountOptions.AllowRememberLogin && model.RememberLogin; // validate username/password against in-memory store var result = await _loginService.PasswordSignInAsync(user, model.Password, rememberMe); if (result.Succeeded || result.RequiresTwoFactor) { var tokenLifetime = _configuration.GetValue("TokenLifetimeMinutes", 120); 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 = new AuthenticationProperties //{ // ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(tokenLifetime), // AllowRefresh = true, // RedirectUri = model.ReturnUrl //}; //if (AccountOptions.AllowRememberLogin && model.RememberLogin) //{ // var permanentTokenLifetime = _configuration.GetValue("PermanentTokenLifetimeDays", 365); // props.ExpiresUtc = DateTimeOffset.UtcNow.AddDays(permanentTokenLifetime); // props.IsPersistent = true; //}; //await _loginService.SignInAsync(user, props); // issue authentication cookie with subject ID and username //await HttpContext.SignInAsync(user.SubjectId, user.Username, props); if (result.RequiresTwoFactor) { return(RedirectToAction("SendCode", "Authority", new { ReturnUrl = model.ReturnUrl, RememberMe = model.RememberLogin })); } 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"); } } if (result.IsLockedOut) { _logger.LogWarning(2, "User account locked out."); return(View("Lockout")); } await _events.RaiseAsync(new UserLoginFailureEvent(model.Username, "invalid credentials")); ModelState.AddModelError(string.Empty, _sharedLocalizer["INVALID_LOGIN_ATTEMPT"]); } // 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) { 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) { 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, clientId : context?.ClientId)); 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", clientId : context?.ClientId)); ModelState.AddModelError(string.Empty, AccountOptions.InvalidCredentialsErrorMessage); } var vm = await BuildLoginViewModelAsync(model); return(View(vm)); }
public async Task <IActionResult> Callback() { // read external identity from the temporary cookie var result = await HttpContext.AuthenticateAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme); if (result?.Succeeded != true) { throw new Exception("External authentication error"); } // lookup our user and external provider info var(user, provider, providerUserId, claims) = await FindUserFromExternalProvider(result); user = await IntegrateExternalUser(provider, providerUserId, claims, user); // if (user == null) // { // // this might be where you might initiate a custom workflow for user registration // // in this sample we don't show how that would be done, as our sample implementation // // simply auto-provisions new external user // user = await IntegrateExternalUser(provider, providerUserId, claims); // } // this allows us to collect any additonal claims or properties // for the specific prtotocols used and store them in the local auth cookie. // this is typically used to store data needed for signout from those protocols. var additionalLocalClaims = new List <Claim>(); var localSignInProps = new AuthenticationProperties(); ProcessLoginCallbackForOidc(result, additionalLocalClaims, localSignInProps); ProcessLoginCallbackForWsFed(result, additionalLocalClaims, localSignInProps); ProcessLoginCallbackForSaml2p(result, additionalLocalClaims, localSignInProps); // issue authentication cookie for user await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.Id, user.UserName)); //await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.SubjectId, user.Username)); await HttpContext.SignInAsync(user.Id, user.UserName, provider, localSignInProps, additionalLocalClaims.ToArray()); //await HttpContext.SignInAsync(user.SubjectId, user.Username, provider, localSignInProps, additionalLocalClaims.ToArray()); // delete temporary cookie used during external authentication await HttpContext.SignOutAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme); // retrieve return URL var returnUrl = result.Properties.Items["returnUrl"] ?? "~/"; // check if external login is in the context of an OIDC request var context = await _interaction.GetAuthorizationContextAsync(returnUrl); 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 = returnUrl })); } } return(Redirect(returnUrl)); }
public async Task <IActionResult> Login(LoginInputModel model, string button) { var context = await identityService.GetAuthorizationContextAsync(model.ReturnUrl); if (button != "login") { if (context != null) { // User has cancelled, pretend they denied the consent to IdentityServer4 // This will return access_denied OIDC error. await identityService.GrantConsentAsync(context, ConsentResponse.Denied); if (await clientStore.IsPkceClientAsync(context.ClientId)) { return(View("Redirect", new RedirectViewModel { RedirectUrl = model.ReturnUrl })); } return(Redirect(model.ReturnUrl)); } else { // No valid context. Go home return(Redirect("~/")); } } if (ModelState.IsValid) { var user = QueryProcessor.Process(new GAME_AuthenticateAndGetUserDetailsQuery { Email = model.Username, EncryptedPassword = model.Password.ToLegacyShaString() }); if (user != UserModel.Default) { await eventService.RaiseAsync(new UserLoginSuccessEvent(user.Email, user.AccountId.ToString(), $"{user.FirstName} {user.LastName}")); // Only set explicit expiration if user chooses "remember me" AuthenticationProperties props = null; if (AccountOptions.AllowRememberLogin && model.RememberLogin) { props = new AuthenticationProperties { IsPersistent = true, ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration) }; } await HttpContext.SignInAsync(user.AccountId.ToString(), user.Email, 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 InvalidOperationException("Invalid return URL"); } } await eventService.RaiseAsync(new UserLoginFailureEvent(model.Username, "invalid credentials")); ModelState.AddModelError("", AccountOptions.InvalidCredentialsErrorMessage); } // Something went wrong to get here var vm = await BuildLoginViewModelAsync(model); return(View(vm)); }
public async Task <IActionResult> Login([FromBody] LoginInputModel model) { // 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 (model.ConfigInfo != "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)); } } // validate username/password var user = await _userManager.FindByNameAsync(model.Username); if (user != null && await _userManager.CheckPasswordAsync(user, model.Password)) { await _events.RaiseAsync(new UserLoginSuccessEvent(user.UserName, user.Id, user.Name)); // 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.Id, user.UserName, props); //return Redirect(model.ReturnUrl); 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 })); } // wedd can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null //return Redirect(model.ReturnUrl); } } 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> OnPostAsync(string button, string returnUrl = null) { // check if we are in the context of an authorization request var context = await _interaction.GetAuthorizationContextAsync(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("~/")); } } returnUrl = returnUrl ?? Url.Content("~/"); 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(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure : true); if (result.Succeeded) { _logger.LogInformation("User logged in."); return(LocalRedirect(returnUrl)); } if (result.RequiresTwoFactor) { return(RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, RememberMe = Input.RememberMe })); } if (result.IsLockedOut) { _logger.LogWarning("User account locked out."); return(RedirectToPage("./Lockout")); } else { ModelState.AddModelError(string.Empty, "Invalid login attempt."); return(Page()); } } // If we got this far, something failed, redisplay form return(Page()); }
public async Task <IActionResult> Callback() { // read external identity from the temporary cookie var result = await HttpContext.AuthenticateAsync(IdentityConstants.ExternalScheme); if (result?.Succeeded != true) { throw new Exception("External authentication error"); } if (_logger.IsEnabled(LogLevel.Debug)) { var externalClaims = result.Principal.Claims.Select(c => $"{c.Type}: {c.Value}"); _logger.LogDebug("External claims: {@claims}", externalClaims); } // lookup our user and external provider info var(user, provider, providerUserId, claims) = await FindUserFromExternalProviderAsync(result); if (user == null) { // this might be where you might initiate a custom workflow for user registration // in this sample we don't show how that would be done, as our sample implementation // simply auto-provisions new external user user = await AutoProvisionUserAsync(provider, providerUserId, claims); } // this allows us to collect any additonal claims or properties // for the specific prtotocols used and store them in the local auth cookie. // this is typically used to store data needed for signout from those protocols. var additionalLocalClaims = new List <Claim>(); var localSignInProps = new AuthenticationProperties(); ProcessLoginCallbackForOidc(result, additionalLocalClaims, localSignInProps); ProcessLoginCallbackForWsFed(result, additionalLocalClaims, localSignInProps); ProcessLoginCallbackForSaml2p(result, additionalLocalClaims, localSignInProps); // issue authentication cookie for user // we must issue the cookie maually, and can't use the SignInManager because // it doesn't expose an API to issue additional claims from the login workflow var principal = await _signInManager.CreateUserPrincipalAsync(user); additionalLocalClaims.AddRange(principal.Claims); var name = principal.FindFirst(JwtClaimTypes.Name)?.Value ?? user.Id; await HttpContext.SignInAsync(user.Id, name, provider, localSignInProps, additionalLocalClaims.ToArray()); // delete temporary cookie used during external authentication await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme); // retrieve return URL var returnUrl = result.Properties.Items["returnUrl"] ?? "~/"; // check if external login is in the context of an OIDC request var context = await _interaction.GetAuthorizationContextAsync(returnUrl); await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.Id, name, true, context?.ClientId)); 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 = returnUrl })); } } return(Redirect(returnUrl)); }
public async Task <IActionResult> Login(LoginInputModel model, string button, string returnUrl = null) { // 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) { // Here we query the database against the user's inputted information var result = await _signInManager.PasswordSignInAsync(model.Username, model.Password, model.RememberLogin, lockoutOnFailure : false); if (result.Succeeded) { 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 { // Refresh the page on invalid login. ModelState.AddModelError(string.Empty, "Invalid login attempt."); return(View(await BuildLoginViewModelAsync(model))); } } // something went wrong, show form with error var vm = await BuildLoginViewModelAsync(model); return(View(vm)); }
public async Task <IActionResult> Callback() { // read external identity from the temporary cookie var result = await HttpContext.AuthenticateAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme); if (result?.Succeeded != true) { throw new Exception("External authentication error"); } if (_logger.IsEnabled(LogLevel.Debug)) { var externalClaims = result.Principal.Claims.Select(c => $"{c.Type}: {c.Value}"); _logger.LogDebug("External claims: {@claims}", externalClaims); } // lookup our user and external provider info var(user, provider, providerUserId, claims) = FindUserFromExternalProvider(result); if (user == null) { // this might be where you might initiate a custom workflow for user registration // in this sample we don't show how that would be done, as our sample implementation // simply auto-provisions new external user user = AutoProvisionUser(provider, providerUserId, claims); } // this allows us to collect any additional claims or properties // for the specific protocols used and store them in the local auth cookie. // this is typically used to store data needed for signout from those protocols. var additionalLocalClaims = new List <Claim>(); var localSignInProps = new AuthenticationProperties(); ProcessLoginCallbackForOidc(result, additionalLocalClaims, localSignInProps); //ProcessLoginCallbackForWsFed(result, additionalLocalClaims, localSignInProps); //ProcessLoginCallbackForSaml2p(result, additionalLocalClaims, localSignInProps); // issue authentication cookie for user var isuser = new IdentityServerUser(user.SubjectId) { DisplayName = user.Username, IdentityProvider = provider, AdditionalClaims = additionalLocalClaims }; await HttpContext.SignInAsync(isuser, localSignInProps); // delete temporary cookie used during external authentication await HttpContext.SignOutAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme); // retrieve return URL var returnUrl = result.Properties.Items["returnUrl"] ?? "~/"; // check if external login is in the context of an OIDC request var context = await _interaction.GetAuthorizationContextAsync(returnUrl); await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.SubjectId, user.Username, true, context?.ClientId)); 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", returnUrl)); } } return(Redirect(returnUrl)); }
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)); } return(Redirect("~/")); } if (ModelState.IsValid) { var user = await _userManager.FindByNameAsync(model.Username); if (user != null && await _userManager.CheckPasswordAsync(user, model.Password)) { await _events.RaiseAsync(new UserLoginSuccessEvent(user.UserName, user.Id, user.Name)); AuthenticationProperties props = null; if (AccountOptions.AllowRememberLogin && model.RememberLogin) { props = new AuthenticationProperties { IsPersistent = true, ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration) } } ; ; await _userManager.AddClaimAsync(user, new Claim("userName", user.UserName)); await _userManager.AddClaimAsync(user, new Claim("name", user.Name)); await _userManager.AddClaimAsync(user, new Claim("email", user.Email)); await _userManager.AddClaimAsync(user, new Claim("role", Roles.Consumer)); await _userManager.AddClaimAsync(user, new Claim("companyName", user.CompanyName)); await HttpContext.SignInAsync(user.Id, 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)); } if (string.IsNullOrEmpty(model.ReturnUrl)) { return(Redirect("~/")); } 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(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(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 var user = await _userManager.FindByNameAsync(model.Username); if (user != null && await _userManager.CheckPasswordAsync(user, model.Password)) { //await _events.RaiseAsync(new UserLoginSuccessEvent(user.UserName, user.Id, user.Name)); // 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.Id, 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)); } var validUrlsForClient = new string[] { //"https://localhost:44344/api/Profile/login/callback", "https://localhost:44344/signin-my-auth-server", "https://localhost:44344/signin-my-auth-server/" }; // Append query-params to redirect-url var redirectUrl = QueryHelpers.AddQueryString(model.ReturnUrl, new Dictionary <string, string> { { "state", model.State }, { "code", Guid.NewGuid().ToString() } }); //var uriBuilder = new UriBuilder(model.ReturnUrl); //var query = System.Web.HttpUtility.ParseQueryString(uriBuilder.Query); ////query["state"] = ; //uriBuilder.Query = query.ToString(); //var redirectUrl = uriBuilder.ToString(); // request for a local page if (Url.IsLocalUrl(model.ReturnUrl)) { return(Redirect(redirectUrl)); } else if (string.IsNullOrEmpty(model.ReturnUrl)) { return(Redirect("~/")); } else if (validUrlsForClient.Contains(model.ReturnUrl)) { return(Redirect(redirectUrl)); } 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)); }