protected override void ResolveDependent() { if (!String.IsNullOrEmpty(_newPassword)) { Byte[] hash; Byte[] salt = new Byte[64]; Byte[] pass = Encoding.UTF8.GetBytes(_newPassword); // Generate a cryptographically-secure random salting value. using (RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider()) provider.GetBytes(salt); // Generate a one-way digest from the salt and password Byte[] data = salt.Concat(pass).ToArray(); using (SHA512CryptoServiceProvider provider = new SHA512CryptoServiceProvider()) hash = provider.ComputeHash(data); // Create a new credential and add to the collection LocalUserCredentialModel credential = this.Provider.Security.UserCredential.Create(); credential.Modified = DateTime.Now; credential.Pass = hash; credential.Salt = salt; this.Credentials.Add(credential); } base.ResolveDependent(); }
/// <summary> /// Authenticates a user account using pre-shared credentials. /// </summary> /// <param name="username"> /// The unique name which distinctly identifies the account to be authenticated. /// </param> /// <param name="password"> /// The pre-shared secret which confirms the identity of the authenticating user. /// </param> /// <returns> /// The <see cref="IUserSessionModel" /> instance for the authenticated user. /// </returns> public void Login(String username, String password) { // Validate the credentials if (String.IsNullOrEmpty(username)) { throw new ArgumentException("Please specify a username."); } if (String.IsNullOrEmpty(password)) { throw new ArgumentException("Please specify a password."); } // Validate the account LocalUserAccountModel userAccount = this.Provider.Security.UserAccount.FetchByUsername(username); if (userAccount == null) { throw new ArgumentException("Incorrect username or password."); } if (userAccount.Credentials.Count == 0) { throw new ArgumentException("Incorrect username or password."); } // Validate the password LocalUserCredentialModel credential = userAccount.Credentials.OrderBy(cred => cred.Modified).LastOrDefault(); using (SHA512 hashAlgoritm = SHA512.Create()) { Byte[] passBytes = Encoding.UTF8.GetBytes(password); Byte[] fullBytes = credential.Salt.Concat(passBytes).ToArray(); Byte[] hashBytes = hashAlgoritm.ComputeHash(fullBytes); Boolean success = hashBytes.SequenceEqual(credential.Pass); userAccount.FailCount = success ? 0 : userAccount.FailCount + 1; userAccount.LastLogin = success ? DateTime.Now : userAccount.LastLogin; userAccount.Save(); if (!success) { throw new ArgumentException("Incorrect username or password."); } else { if (userAccount.Status == 0) { throw new ArgumentException("Your account is inactive."); } else { var licenseLimit = this.Provider.Security.LicenseLimit.FetchAll().Where(x => (int)x.Type == userAccount.LicenseType).FirstOrDefault(); if (licenseLimit != null) { //Checks total number of Licenses currently in use var totalUserSessions = this.Provider.Security.UserSession.FetchAll().Where(x => x.Status == UserSessionStates.Active && x.User.LicenseType == userAccount.LicenseType).OrderByDescending(x => x.Active).Select(x => x.UserId).Distinct().ToList(); //Checks if already logged in user signs in again var isSameUser = totalUserSessions.ToList().Any(x => x == userAccount.Id); if (!isSameUser && totalUserSessions.Count >= licenseLimit.Value) { throw new ArgumentException("All licences are currently in use."); } if (isSameUser && totalUserSessions.Count > licenseLimit.Value) { throw new ArgumentException("All licences are currently in use."); } } } } } // Create the new session LocalUserSessionModel session = this.Provider.Security.UserSession.Create(); session.UserId = userAccount.Id; session.Active = DateTime.Now; session.Expiry = DateTime.Now.AddMinutes(HttpContext.Current.Session.Timeout); session.Save(); // Persist and return the session HttpContext.Current.Session[LocalUserSessionFactory.SessionKey] = session; }