public async Task <IActionResult> Login([FromBody] SessionCreateForm form) { // El form está comlpeto? -------------------- if (form == null) { return(new BadRequestResult()); } if (string.IsNullOrEmpty(form.UsernameOrEmail)) { ModelState.AddModelError(nameof(form.UsernameOrEmail), "Required"); } if (string.IsNullOrEmpty(form.Password)) { ModelState.AddModelError(nameof(form.Password), "Required"); } if (!ModelState.IsValid) { return(ValidationError()); } // La IP tiene permiso de intentar login? -------------------- var attemptRateResult = await LoginAttemptLimitingService.Check(RequestInfoService.RemoteIp, LoginAttemptStore); if (!attemptRateResult.IsApproved) { ModelState.AddModelError("", attemptRateResult.ErrorMessage); return(ValidationError()); } LoginAttempt attempt = new LoginAttempt(this.RequestInfoService.RemoteIp, DateTime.UtcNow); // La credencial existe? -------------------- string failedLoginMsg = "Invalid email and password combination."; Credential credential = null; bool isEmail = form.UsernameOrEmail.IsEmail(); if (isEmail) { credential = await CredentialStore.GetByEmail(form.UsernameOrEmail); } else { credential = await CredentialStore.Get(form.UsernameOrEmail); } if (credential == null) { ModelState.AddModelError("", failedLoginMsg); await LoginAttemptStore.Create(attempt); return(ValidationError()); } // La contraseña es correcta? string newCalculatedHash = HashingUtil.GenerateHash(form.Password, credential.PasswordSalt); if (newCalculatedHash != credential.PasswordHash) { ModelState.AddModelError("", failedLoginMsg); await LoginAttemptStore.Create(attempt); return(ValidationError()); } // El usuario está penalizado? CredentialPenalty activePenalty = await CredentialPenaltyStore.Get(credential.CredentialId, DateTime.UtcNow); if (activePenalty != null) { string validationMsg = null; if (activePenalty.EndDate.HasValue) { validationMsg = string.Format("User temporarily banned, until [{0}]. Reason: '{1}'", activePenalty.EndDate.Value.ToString(), activePenalty.Reason); } else { validationMsg = string.Format("User permanently banned. Reason: '{0}'", activePenalty.Reason); } ModelState.AddModelError("", validationMsg); await LoginAttemptStore.Create(attempt); return(ValidationError()); } var agent = RequestInfoService.UserAgent; // La credencial ya tiene una sesión activa? Session session = await this.SessionStore.Get( credential.CredentialId, agent.DeviceClass, agent.DeviceName, agent.AgentName, agent.AgentVersion); if (session != null) { session.LastActiveDate = DateTime.UtcNow; if (session.AllowSelfRenewal) { session.ExpirationDate = session.LastActiveDate.AddDays(1); } await SessionStore.Update(session); } else { // Crea la sesión session = new Session(); session.CredentialId = credential.CredentialId; session.LoginDate = DateTime.UtcNow; session.ExpirationDate = DateTime.UtcNow.AddDays(1); session.LastActiveDate = session.LoginDate; session.AllowSelfRenewal = form.IsRememberLogin; session.Device = new UserDevice(agent.DeviceClass, agent.DeviceName); session.Agent = new UserAgent(agent.AgentName, agent.AgentVersion); await SessionStore.Create(session); } // Autentifica // check if we are in the context of an authorization request var context = await _interaction.GetAuthorizationContextAsync(form.ReturnUrl); await _events.RaiseAsync(new UserLoginSuccessEvent(credential.DisplayName, credential.CredentialId, credential.DisplayName, 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 (form.IsRememberLogin) { props = new AuthenticationProperties { IsPersistent = true, ExpiresUtc = DateTimeOffset.UtcNow.Add(TimeSpan.FromHours(8)) }; } ; // issue authentication cookie with subject ID and username var isuser = new IdentityServerUser(credential.CredentialId) { DisplayName = credential.DisplayName }; await HttpContext.SignInAsync(isuser, props); // Devuelve el recurso Session return(Element <Session>(session)); }