/// <summary> /// Inserts a new user authentication history. /// </summary> /// <param name="history"></param> protected override void InsertUserHistory(AuthenticationHistory history) { TableProxyAuthenticationHistoryByUserName.Insert(history); if (history.UserSession != null && !history.UserSession.RenewalToken.Equals(Guid.Empty)) { TableProxyAuthenticationHistoryByToken.InsertOrUpdate(history); } }
public void Constructor_GiveValidArguments_PropertiesAreSet() { var authenticationHistory = new AuthenticationHistory( TestVariables.AuthenticationHistoryId, TestVariables.Now, AuthenticationHistoryType.Success); Assert.Equal(TestVariables.AuthenticationHistoryId, authenticationHistory.Id); Assert.Equal(TestVariables.Now, authenticationHistory.WhenHappened); Assert.Equal(AuthenticationHistoryType.Success, authenticationHistory.AuthenticationHistoryType); foreach (var prop in authenticationHistory.GetType().GetProperties().Where(x => x.PropertyType.Name == "IReadOnlyList`1")) { var val = prop.GetValue(authenticationHistory, null); Assert.False(val == null, $"{prop.Name} is null"); } }
private void InsertUserHistory(AuthenticationHistory history) { using (var cn = new SqlConnection(ConnectionStringAudit)) { cn.Open(); using (var cmd = new SqlCommand()) { cmd.Connection = cn; cmd.CommandType = System.Data.CommandType.Text; cmd.CommandText = @"insert into Security.AuthenticationHistory (UserName, IpAddress, IsAuthenticated) Values (@UserName, @IpAddress, @IsAuthenticated)"; cmd.Parameters.AddWithValue("UserName", history.UserName); cmd.Parameters.AddWithValue("IpAddress", history.IPAddress); cmd.Parameters.AddWithValue("IsAuthenticated", history.IsAuthenticated); cmd.ExecuteNonQuery(); } } SaveUserSession(history.UserSession); }
public void LogAuthentication(AuthAttemptType attemptType, string userName, string emailAddress, Guid clientId, string bogusData = null) { var now = DateTime.UtcNow; var history = new AuthenticationHistory() { AuthenticationHistoryId = Guid.NewGuid(), Username = userName, EmailAddress = emailAddress, ClientId = clientId, BogusData = bogusData, Type = attemptType.ToString(), CreatedById = Guid.Empty, CreatedDate = now, UpdatedById = Guid.Empty, UpdatedDate = now, Deleted = false, }; _context.AuthenticationHistories.Add(history); _context.SaveChanges(); }
/// <summary> /// Authenticates against the data store and returns a UserIdentity given /// a token returned from a previous authentication. /// </summary> /// <param name="token">The unique token.</param> /// <param name="duration">The amount of time that the renewed token will be valid.</param> /// <param name="ipAddress">The internet address where the user is connecting from.</param> /// <param name="result">A ExecutionResults instance to add applicable /// warning and error messages to.</param> /// <returns> /// A valid user identity instance. If the token is incorrect or expired /// then the IsAuthenticated flag will be false. Otherwise the identity /// will be authenticated. /// </returns> public override UserIdentity AuthenticateUser(string token, UserSessionDurationType duration, String ipAddress, ExecutionResults result) { String errorMsg = "Authentication token invalid."; Guid renewalToken; if (!Guid.TryParse(token, out renewalToken)) { result.AppendError(errorMsg); return(new cs.UserIdentity()); } UserSession session = GetUserSession(renewalToken); if (session == null) { result.AppendError(errorMsg); return(new cs.UserIdentity()); } AuthenticationHistory history = GetSessionAuthenticationHistory(session); if (history == null) { result.AppendError(errorMsg); return(new cs.UserIdentity()); } else if (history.IPAddress != ipAddress) { //coming from a new IPAddress, token was stolen or user is coming from a new dynamic IP address (new internet connection?) result.AppendError(errorMsg); return(new cs.UserIdentity()); //force new login with password (essentially approves this new IP address) //WARN: is this a valid check? Can an imposter just fake the source IP? Could a legitimate user hop IP Addresses during a single session? } session.RenewedDate = DateTime.UtcNow; session.ExpirationDate = DateTime.UtcNow.AddMinutes(duration == UserSessionDurationType.PublicComputer ? PublicSessionDuration : ExtendedSessionDuration); SaveUserSession(session); history.UserSession = session; return(new UserIdentity(history, this.Name)); }
private cs.UserIdentity AuthenticateUser(string name, string password, UserSessionDurationType duration, string ipAddress, bool checkHistory, bool allowUpdateHash, ExecutionResults result) { if (checkHistory) { var recentFailures = GetRecentFailedUserNameAuthenticationCount(name); if (recentFailures > AllowedFailuresPerPeriod) { return(FailAuthenticateUser(name, ipAddress, result)); } } User user = GetUserByName(name); if (user == null) { return(FailAuthenticateUser(name, ipAddress, result)); } UserSalt salt = GetUserSalt(user.UserID); if (salt == null) { return(FailAuthenticateUser(name, ipAddress, result)); } //this should get a named hashProvider used to originally hash the password... // fallback to 'default' provider in legacy case when we didn't store the name. HashProvider hasher = !string.IsNullOrEmpty(salt.HashName) ? HashManager.Providers[salt.HashName] : HashManager.DefaultProvider; var passwordHash = hasher.Hash(salt.PasswordSalt, password, salt.HashGroup + BaseHashIterations); if (user.PasswordHash != passwordHash) { return(FailAuthenticateUser(name, ipAddress, result)); } var session = new UserSession { CreatedDate = DateTime.UtcNow, ExpirationDate = DateTime.UtcNow.AddMinutes(duration == UserSessionDurationType.PublicComputer ? PublicSessionDuration : ExtendedSessionDuration), UserID = user.UserID, RenewalToken = Guid.NewGuid() }; var history = new AuthenticationHistory { IPAddress = ipAddress, IsAuthenticated = true, UserName = name, UserSession = session }; using (var scope = new System.Transactions.TransactionScope()) { if (allowUpdateHash && (hasher.IsObsolete || user.PasswordHashUpdatedDate < DateTime.UtcNow.AddMonths(-1))) { //update hashes on regular basis, keeps the iterations in latest range for current users, and with a 'current' hash provider. hasher = HashManager.SelectProvider(); salt.PasswordSalt = hasher.GetSalt(); salt.HashGroup = new Random(DateTime.Now.Second).Next(HashGroupMinimum, HashGroupMaximum); salt.HashName = hasher.Name; user.PasswordHash = hasher.Hash(salt.PasswordSalt, password, salt.HashGroup + BaseHashIterations); user.PasswordHashUpdatedDate = DateTime.UtcNow; //starts as a lightweight transaction SaveUser(user); //enlists in a full distributed transaction if users and salts have different connection strings SaveUserSalt(salt); } //either continues distributed transaction if applicable, // or creates a new lightweight transaction for these two commands SaveUserSession(session); InsertUserHistory(history); } return(new cs.UserIdentity(history, this.Name)); }
/// <summary> /// Inserts a new user authentication history. /// </summary> /// <param name="history"></param> protected override void InsertUserHistory(AuthenticationHistory history) { TableProxyAuthenticationHistoryByUserName.Insert(history); if (history.UserSession != null && !history.UserSession.RenewalToken.Equals(Guid.Empty)) TableProxyAuthenticationHistoryByToken.InsertOrUpdate(history); }
protected override void InsertUserHistory(AuthenticationHistory history) { throw new NotImplementedException(); }