UserManager не может изменить 5% всех учетных записей - PullRequest
0 голосов
/ 27 сентября 2018

Текущий проект:

У меня возникла очень странная проблема с перенастроенной базой данных.Старая база данных не может быть спасена (неправильный дизайн, неправильно введенные данные, работы), поэтому для клиента была разработана и построена совершенно новая система.

Из-за плохого состояния данных миграция была вынужденанаказание через Excel, чтобы можно было очистить данные и выполнить некоторые сложные вычисления и проверки для определенных полей.

Я повторно импортировал данные таким образом, что для пользователей, их полей PasswordHash и SecurityStampбыли нулевые значения (настройка по умолчанию).Затем я запустил в браузере безголовый скрипт (ActionResult, который просто перенаправил обратно в / Home / Index после того, как это было сделано), который прошел через всех пользователей и назначил им случайный GUID в качестве пароля.Предполагалось, что электронное письмо для сброса пароля будет разослано всем.

К сожалению, для 102 пользователей из более чем 2000 этот сценарий без заголовка не смог обновить пользователя.Например, PasswordHash и SecurityStamp оставались нулевыми.

Эта проблема теперь распространяется на сообщение электронной почты для сброса пароля, которое было отправлено.Ссылка в каждом электронном письме работает, так как она способна сбросить 95% всех учетных записей, но для этих 102 учетных записей она совершенно не может очистить, установить или сбросить пароль.Я попытался отладить это, но отладчик не погружается в UserManager (понятно), и поэтому я не могу увидеть, где и как он выходит из строя.

Поскольку 95% всех учетных записей работают нормально, единственное, чтоЯ могу придумать, что с базой данных что-то не так, что UserManager не может обновить эти конкретные строки.К сожалению, тщательное изучение таблицы «Пользователь» не показывает каких-либо особых различий между 102 затронутыми учетными записями и любой незатронутой учетной записью - нет согласованности с этими 102 всплывающими учетными записями.

Попытки установить оба поля в некоторыезначение через MSSQL, включая пустые строки, не имеет значения.

Предложения?Честно говоря, я понятия не имею, что нужно показать или какие дополнительные вопросы мне следует задавать в это время.


РЕДАКТИРОВАТЬ

MASSIVE WHISKY-Момент TANGO-FOXTROT здесь, ребята.

Оказывается, что IS сходство между всеми учетными записями ... ИМЕНА ПОЛЬЗОВАТЕЛЕЙ все имеют нецифровую,нецелые символы.Как плюс (+) или тире (-).Проблема в том, что дефисы часто встречаются во многих доменных именах (не говоря уже о самом имени пользователя электронной почты), а плюсы широко используются в плюс-адресации для определенных провайдеров, таких как gMail.

Я подтвердил, что добавлениеплюс или тире в любой части имени пользователя приводит к сбою любого вида набора, удаления или сброса пароля через UserManager.

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

Так ясно что-нибудь в имени пользователяэто не аз, 0-9 и.вызывает невероятный сбой UserManager.

Как это происходит, мне не под силу.Я буквально не могу даже.

Я ищу руководство и руководство по этому вопросу, потому что мой разум - не что иное, как множество маленьких осколков по всему моему офису прямо сейчас.Мне нужно иметь возможность принимать тире и плюсы в именах пользователей, не перекрывая весь набор функций установки / удаления / сброса пароля.

PlЛегко также понять, что эта система использует систему DotNet - все, что здесь происходит, выходит за рамки всего, что я лично коснулся.Единственный возможный способ проникновения чего-либо - это то, что обычная запись имени пользователя через веб-форму имеет свое имя пользователя, «очищенное» так, что такие вещи, как тире и плюсы, фактически не являются таковыми в поле базы данных UserName.

1 Ответ

0 голосов
/ 27 сентября 2018

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

. Поскольку я сильно озабочен вопросами безопасности и ненавижу класть все яйца в одну корзину, я никогда не буду использовать сторонние логины, такие как Facebook или Google.Это представляет собой единственную точку отказа, которую ни один веб-сайт не должен обременять пользователем.Таким образом, я смог игнорировать эту расширенную функциональность Identity 2.0.Это влияет на то, что я делаю?Понятия не имею, но это утверждение только для справки.

То, что дало мне подсказку для обходного пути, было это сообщение .

Теперь мой _userManager не дёптал оптом, была только его способность писать в БД, и только тогда, когда поле UserName БД содержало адрес электронной почты, который содержал плюс или тире.Поэтому я все еще могу использовать UserManager, я просто не могу использовать его функции сохранения в БД.

Например, мой оригинальный скрипт сброса выглядел такthis:

[HttpPost]
[ValidateAntiForgeryToken]
[ValidateSecureHiddenInputs("ResetId")]
public async Task<ActionResult> Reset(ResetViewModel model) {
  if(!ModelState.IsValid) return View("Reset", model);
  try {
    var reset = await CheckReset(model.ResetId);
    if(!(await _userManager.AddPasswordAsync(reset.UserId, model.NewPassword)).Succeeded) throw new Exception(@"We were able to erase the old password, but were unable to set a new password. Please contact [] with all details for a resolution.");
    await ProcessReset(model.ResetId);
    return RedirectToAction("ResetSuccessful", "Home");
  } catch(Exception e) {
    return View("ResetError", new ResetErrorViewModel(e.Message));
  }
}

Что не удалось, так это _userManager.AddPasswordAsync(), и он сделал это тихо - без исключения, без сообщения об ошибке БД.Он просто не смог вставить новый пароль и испортил свои куки-файлы по всему, что пыталось использовать его для прикосновения к любой учетной записи с плюсом или тире в имени пользователя.

Мой исправленный код таков:

[HttpPost]
[ValidateAntiForgeryToken]
[ValidateSecureHiddenInputs("ResetId")]
public async Task<ActionResult> Reset(ResetViewModel model) {
  if(!ModelState.IsValid) return View("Reset", model);
  try {
    var r = await CheckReset(model.ResetId);
    var u = await _unitOfWork.UserRepository.FindByIdAsync(r.UserId);
    new UserMap().ResetPassword(u, _userManager.PasswordHasher.HashPassword(model.NewPassword));
    _unitOfWork.UserRepository.Update(u);
    if(await _unitOfWork.SaveChangesAsync() < 1) throw new Exception(@"We were unable to set a new password. Please contact [] with all details for a resolution.");
    await ProcessReset(r.ResetId);
    return RedirectToAction("ResetSuccessful", "Home");
  } catch(Exception e) {
    return View("ResetError", new ResetErrorViewModel(e.Message));
  }
}

Заметили разницу?Я вызываю позицию, используя _unitOfWork и только кредитное плечо _userManager до , предоставляю мне хешированный пароль - я оставляю сохранение этого пароля в базе данных на _unitOfWork, который прекрасно работает!

К вашему сведению, new UserMap().ResetPassword() - это пользовательский класс сопоставления, который я предпочитаю использовать вместо автомпера из-за проблем управления.

Я расширил использование _userManager к методу регистрации пользователя, и подтвердили, что теперь он полностью функционален для обоих методов.

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