Как я могу использовать linq для аутентификации имени пользователя / пароля? - PullRequest
2 голосов
/ 08 сентября 2010

Я все еще изучаю LINQ.Я могу сделать несколько простых запросов, но этот немного отличается.У меня есть следующий запрос, который аутентифицирует пользователя.

User user = (from u in db.Users
             where u.Username.Equals(username) &&  
                   u.Password.Equals(UserSecurity.GetPasswordHash(username, password)) &&
                   u.Status == true                  
             select u).FirstOrDefault();

Это работает, но теперь мне нужно войти, почему не удалось войти в систему.Если было неверное имя пользователя, я запишу одну вещь.Если пароль был неправильным, я войду другой.Или, если пользователь неактивен (status = false), я зарегистрирую другого.Я понимаю, что могу разделить это на 3 отдельных запроса, чтобы выяснить, что не удалось, но мне было интересно, будет ли эффективнее сделать это в одном.Если так, то как?Это мой (не проверенный) подход с тремя запросами.

            User user2 = null;

            var users1 = db.Users.Where(i => i.Username.Equals(username));

            if (users1 != null)
            {
                var users2 = users1.Where(i => i.Password.Equals(UserSecurity.GetPasswordHash(username, password)));

                if (users2 != null)
                {
                    var users3 = users2.Where(i => i.Status);

                    if (users3 != null)
                    {
                        user2 = users3.FirstOrDefault();
                    }
                    else
                    {
                        // User inactive
                    }
                }
                else
                {
                    // Password invalid.
                }
            }
            else
            {
                // Username invalid
            }

Ответы [ 2 ]

9 голосов
/ 08 сентября 2010

Не следует указывать, что имя пользователя указано правильно, или указывать, что пароль неверный, должно быть достаточно «Неверное имя пользователя или пароль».И характерно для большинства систем.

Это оставляет вас с проверкой статуса, если комбинация имени пользователя / пароля была правильной, то у вас есть возвращенная запись пользователя, и вы можете проверить статус из этого.

User user = (from u in db.Users 
     where u.Username.Equals(username) &&   
           u.Password.Equals(UserSecurity.GetPasswordHash(username, password))
     select u).FirstOrDefault(); 

if (user == null)
{
  // Invalid user name or password
}
else if (user.Status != true)
{
  // User inactive
}
else
{
  // Success
}

Если вы хотите указать разницу между неверным именем пользователя и неверным паролем, вы можете сделать следующее.

User user = (from u in db.Users 
     where u.Username.Equals(username)
     select u).FirstOrDefault();

if  (user == null)
{
  // Invalid user name
}
else if (!user.password.Equals(...))
{
  // Invalid password
}
else if (user.Status != true)
{
  // User inactive
}
else
{
  // Success
}
1 голос
/ 08 сентября 2010

Я не думаю, что в этом случае требуется использование Linq только для "использования linq".

При этом я использую метод расширения SequenceEqual байтового массива для сравнения двуххешированный парольЯ обычно храню свой пароль как двоичный файл (64) в моей базе данных (вместе с двоичным кодом соли (16))

Это мой типичный подход (более или менее) для проверки пароля.Я изменил его, чтобы включить поиск Linq, как ваш пример

public bool AuthenticateUser(string username, string password)
{
    // I don't validate password here (see TODO below)
    var user = db.User.FirstOrDefault(u => u.UserName == username && u.Status);

    if(user != null)
    {
        var rehash = Hashing.Hash(password, user.PasswordSalt); // PasswordSalt is a byte array
        if(rehash.SequenceEqual(user.Password))
        {
            return true;
        }
        else
        {
            Logger.LogUnsuccessfulAuthentication(user);

            // TODO: Increase user-login failure count and system-wide failure count
        }
    }

    return false;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...