Миграция существующих пользователей и паролей в новую пользовательскую систему Symfony / sfDoctrineGuard - PullRequest
2 голосов
/ 08 февраля 2011

У меня есть существующий, не основанный на фреймворке сайт PHP / MySQL. Он имеет простую модель безопасности с таблицей пользователей с именами пользователей и хешированными (MD5) паролями.

В настоящее время я работаю над "версией 2" этого сайта, на этот раз используя Symfony с Doctrine. Новая версия работает нормально, и я использую плагин sfDoctrineGuard для управления пользователями.

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

Текущий сайт использует несоленые хеши паролей MD5 *. Я уже выяснил, как перенести пользователей в Symfony / sfDoctrineGuard, сохранив при этом существующий алгоритм (предоставив свою собственную функцию «алгоритма» для несоленого MD5.) Но несоленый md5 явно не идеален.

Итак, мой вопрос, учитывая, что группа пользователей может успешно перейти на пользователей sfDoctrineGuard с помощью моего пользовательского алгоритма хеширования пароля обычного MD5, есть ли способ преобразовать этих пользователей, чтобы они использовали стандартный, соленый Алгоритм SHA1 sfDoctrineGuard?

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

Я немного покопался и не могу найти способ переопределить или подключить систему входа в систему sfDoctrineGuard (в частности, sfGuardSecurityUser, я думаю?) В нужной точке. Ну, не без взлома с фактическими файлами плагинов, которые кажутся злыми.

Могут ли какие-нибудь эксперты Symfony / sfDoctrineGuard показать мне правильное направление?

* Не смотри на меня так, это был мой первый сайт! И, по крайней мере, я не сохранил их в открытом виде ...

Ответы [ 2 ]

1 голос
/ 09 февраля 2011

У вас есть много вариантов для решения ваших проблем.

Вы можете перегрузить или изменить почти все в sfDoctrineGuardPlugin.

Если вам нужно что-то изменить в sfGuardSecurityUser, чем вы можете это сделать в классе User вашего приложения (который фактически расширяет sfGuardSecurityUser).

Также возможно перегрузить классы моделей, которые по умолчанию помещаются в каталог lib / model / doctrine / sfDoctrineGuardPlugin.

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

Наконец, вы можете реализовать свой собственный алгоритм проверки и настройки пароля: http://www.symfony -project.org / plugins / sfDoctrineGuardPlugin? Tab = plugin_readme (выделите «Проверить пароль пользователя с помощью внешнего метода» и «Изменить алгоритм, используемый для хранения паролей»).

0 голосов
/ 09 февраля 2011

Спасибо Кубе, который указал мне точно правильное направление.

Чтобы помочь кому-то еще, кто хотел сделать что-то подобное, вот что я сделал.

Сначала я перенес своих существующих пользователей (используя загрузку из текстовых файлов, выгруженных из старой базы данных) в свою базу данных. Я использовал собственный алгоритм, который оставлял мои несоленые пароли MD5 неизменными во время загрузки данных (называемый UniqueSentence :: unsaltednotransform). Это дало мне пользователей в sf_guard_user со старыми хэшами паролей в «пароле» и «UniqueSentence :: unsaltednotransform» в «алгоритме». (Вы также можете просто перенести строки в таблицу напрямую, мне просто удобно иметь мои в качестве фиксаторов.)

Затем я добавил собственную настраиваемую функцию checkPassword в /lib/model/doctrine/sfDoctrineGuardPlugin/sfGuardUser.class.php следующим образом:

class sfGuardUser extends PluginsfGuardUser
{
  public function checkPassword($password)
  {
    if ($this->getAlgorithm() == 'UniqueSentence::unsaltednotransform') {
      // Our password has been set by a fixture load that left it in its
      // original state from the old system, an unsalted MD5.

      // Has the user got the right password?
      if (md5($password) != $this->getPassword()) {
        return false;
      }
      // Yes. So, now we re-set the password.
      $this->setSalt(''); // An empty salt will be regenerated
      // Use a smarter algorithm
      $algorithm = sfConfig::get('app_sf_guard_plugin_algorithm_callable', 'sha1');
      $this->setAlgorithm($algorithm); 
      $this->setPassword($password);
      // Could just return true here, but dropping through to the usual
      // method means that if we've broken something, we'll know sooner 
      // rather than later.
    }
    // Just pass the call onto the usual method.
    return parent::checkPasswordByGuard($password);
  }
}

Как видите, все довольно просто - если он обнаруживает пользователя, у которого есть старый алгоритм паролей, он проверяет пароль, используя старый алгоритм, а затем, если это правильный пароль, он меняет алгоритм на SHA1, и переустанавливает пароль (сначала устанавливает соль пустым, чтобы он также восстанавливался). Затем он просто переходит к использованию стандартного checkPassword () в базовом классе.

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

...