Как проверить, равен ли введенный пароль сохраненному паролю? - PullRequest
0 голосов
/ 15 октября 2018

Предположим, я реализовал способ изменения пароля в панели пользователя.Прежде чем вносить изменения, я прошу пользователя ввести текущий пароль, я фактически создал этот метод:

[HttpPost]
[ValidateAntiForgeryToken]
public bool CheckCurrentPassword(string username, string password)
{
    var originalUser = _userManager.Users.FirstOrDefault(c => c.UserName == username);
    var hash = _userManager.PasswordHasher.HashPassword(originalUser, password);

    if (hash == originalUser.PasswordHash)
        return true;

    return false;
}

по сути, я отправляю этому методу username, который является уникальным полем, и я могу получитьпользователь, который попросил сменить пароль.Я также получаю хэш нового пароля, а затем сравниваю его с сохраненным в базе данных хешем.

Проблема в том, что хеш отличается.Я не знаю почему, но с одним и тем же паролем у меня есть два разных хэша (один хранится в БД), а другой сгенерирован на лету методом.

Возможно, есть другой способ проверить, является ли текущий парольравен введенному паролю?

Ответы [ 3 ]

0 голосов
/ 15 октября 2018

Я также столкнулся с этой проблемой, она была вызвана тем, что хеширование, которое было сделано в проекте MVC, каким-то образом манипулировалось базой данных SQL, так что таким образом (ниже) мне удалось обойти проблему наличиянесоответствие в хешированном пароле при сравнении введенного пароля и сравнения с существующим паролем в базе данных SQL.

Можно попробовать несколько иной способ сравнения введенного пароля с существующим паролем.

public ActionResult Login(UserLogin login)
{

  var v = dc.Users.Where(a => a.UserEmailAddress == login.UserEmailAddress).FirstOrDefault();

  if(string.Compare(Crypto.Hash(login.UserPassword), v.UserPassword) == 0)
  {
     //do login here
  }
}

Таким образом, если ваш контроллер настроен на прием данных для входа в форму, вы сможете использовать «логин», чтобы найти пользователя в базе данных, в которую вы пытаетесь войти. Этот пользователь будет найден взапрос, вы можете приступить к выполнению "string.Compare"

Я надеюсь, это поможет.

0 голосов
/ 15 октября 2018

Это именно то, для чего UserManager<TUser>.CheckPasswordAsync(TUser, String):

if (await _userManager.CheckPasswordAsync(originalUser, password))
{
    // Yes, it's the current password.
}

Пока вы в этом, лучше использовать UserManager.FindByNameAsync (String) чтобы получить originalUser.Вся функция может выглядеть следующим образом:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<bool> CheckCurrentPassword(string username, string password)
{
    var originalUser = await _userManager.FindByNameAsync(username);

    // originalUser might be null (as in your example), so check for that accordingly.

    return await _userManager.CheckPasswordAsync(originalUser, password);
}

Для использования методов Async требуется, чтобы в вызывающем коде использовался async/await, который я свернул в приведенном выше примере.Действия поддерживают это из коробки;обработка типа возврата Task<T>.

Если вам интересно, как реализована функция CheckPasswordAsync, вы можете убедиться в исходном коде , который может помочь вамопределить, почему ваша собственная версия не работает.

0 голосов
/ 15 октября 2018

Если хеши отличаются, то метод, используемый для хеширования пароля перед его вводом в базу данных, должен отличаться от _userManager.PasswordHasher.HashPassword.Не могу придумать другого объяснения.Посмотрите, сможете ли вы сопоставить два способа хеширования.

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