A single authenticated session for a user.
Exemplo n.º 1
0
 protected override void SaveUserSession(UserSession session)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 2
0
 /// <summary>
 /// Saves a user session, insert or update.
 /// </summary>
 /// <param name="session"></param>
 protected abstract void SaveUserSession(UserSession session);
Exemplo n.º 3
0
 protected override AuthenticationHistory GetSessionAuthenticationHistory(UserSession session)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 4
0
        /// <summary>
        /// Authenticates a user with the requested rule options.  This internal method is called
        /// by the other public versions of the method.  Override in a derived class if you want
        /// to change the rule interpretations or add new rules.
        /// </summary>
        /// <param name="name"></param>
        /// <param name="password"></param>
        /// <param name="duration"></param>
        /// <param name="ipAddress"></param>
        /// <param name="checkHistory"></param>
        /// <param name="allowUpdateHash"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        protected virtual 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);
            }
            var user = GetUserByName(name);
            if (user == null)
                return FailAuthenticateUser(name, ipAddress, result);
            var 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.
            var 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
            {
                CreatedDate = session.CreatedDate,
                IPAddress = ipAddress,
                IsAuthenticated = true,
                UserName = name,
                SessionID = session.SessionID,
                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);
                scope.Complete();
            }
            return new UserIdentity(history, Name);
        }
Exemplo n.º 5
0
 /// <summary>
 /// Gets the authentication history for a specific session.
 /// </summary>
 /// <param name="session"></param>
 /// <returns></returns>
 protected abstract AuthenticationHistory GetSessionAuthenticationHistory(UserSession session);
Exemplo n.º 6
0
 /// <summary>
 /// Saves a user session, insert or update.
 /// </summary>
 /// <param name="session"></param>
 protected override void SaveUserSession(UserSession session)
 {
     using (var cn = new SqlConnection(ConnectionStringAudit))
     {
         cn.Open();
         using (var cmd = new SqlCommand())
         {
             cmd.Connection = cn;
             cmd.CommandType = System.Data.CommandType.Text;
             if (session.SessionID == 0)
             {
                 cmd.CommandText = @"insert into Security.UserSession
      (UserID, RenewalToken, ExpirationDate)
      Values (@UserID, @RenewalToken, @ExpirationDate)";
                 cmd.Parameters.AddWithValue("UserID", session.UserID);
                 cmd.Parameters.AddWithValue("RenewalToken", session.RenewalToken);
                 cmd.Parameters.AddWithValue("ExpirationDate", session.ExpirationDate);
             }
             else
             {
                 cmd.CommandText = @"update Security.UserSession
      set ExpirationDate = @ExpirationDate,
      RenewedDate = @RenewedDate
      where SessionID = @SessionID";
                 cmd.Parameters.AddWithValue("ExpirationDate", session.ExpirationDate);
                 cmd.Parameters.AddWithValue("RenewedDate", session.RenewedDate);
                 cmd.Parameters.AddWithValue("SessionID", session.SessionID);
             }
             cmd.ExecuteNonQuery();
         }
     }
 }
Exemplo n.º 7
0
 /// <summary>
 /// Gets the authentication history for a specific session.
 /// </summary>
 /// <param name="session"></param>
 /// <returns></returns>
 protected override AuthenticationHistory GetSessionAuthenticationHistory(UserSession session)
 {
     using (var cn = new SqlConnection(ConnectionStringAudit))
     {
         cn.Open();
         using (var cmd = new SqlCommand())
         {
             cmd.Connection = cn;
             cmd.CommandType = System.Data.CommandType.Text;
             cmd.CommandText = @"Select top 1 RecordID, UserName, IPAddress, CreatedDate, IsAuthenticated, SessionID
      from Security.AuthenticationHistory
      where SessionID = @SessionID
      and IsAuthenticated == 1
      order by CreatedDate desc";
             cmd.Parameters.AddWithValue("SessionID", session.SessionID);
             using (var reader = cmd.ExecuteReader())
             {
                 if (reader.Read())
                 {
                     return new AuthenticationHistory
                         {
                         RecordID = reader.GetInt32("RecordID", 0),
                         UserName = reader.GetString("UserName", ""),
                         IPAddress = reader.GetString("IPAddress", ""),
                         CreatedDate = reader.GetUTCDateTime("CreatedDate", DateTime.MinValue),
                         IsAuthenticated = reader.GetBoolean("IsAuthenticated", false),
                         SessionID = session.SessionID,
                         UserSession = session
                     };
                 }
             }
         }
     }
     return null;
 }
Exemplo n.º 8
0
 /// <summary>
 /// Gets the authentication history for a specific session.
 /// </summary>
 /// <param name="session"></param>
 /// <returns></returns>
 protected abstract AuthenticationHistory GetSessionAuthenticationHistory(UserSession session);
Exemplo n.º 9
0
 /// <summary>
 /// Saves a user session, insert or update.
 /// </summary>
 /// <param name="session"></param>
 protected abstract void SaveUserSession(UserSession session);
Exemplo n.º 10
0
        /// <summary>
        /// Authenticates a user with the requested rule options.  This internal method is called
        /// by the other public versions of the method.  Override in a derived class if you want
        /// to change the rule interpretations or add new rules.
        /// </summary>
        /// <param name="name"></param>
        /// <param name="password"></param>
        /// <param name="duration"></param>
        /// <param name="ipAddress"></param>
        /// <param name="checkHistory"></param>
        /// <param name="allowUpdateHash"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        protected virtual 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));
                }
            }
            var user = GetUserByName(name);

            if (user == null)
            {
                return(FailAuthenticateUser(name, ipAddress, result));
            }
            var 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.
            var 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
            {
                CreatedDate     = session.CreatedDate,
                IPAddress       = ipAddress,
                IsAuthenticated = true,
                UserName        = name,
                SessionID       = session.SessionID,
                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);
                scope.Complete();
            }
            return(new UserIdentity(history, Name));
        }