CakePHP 2: переопределить метод "пароль" AuthComponent

Моя цель - иметь уникальную соль для каждого пользователя, а не просто использовать Configure::read('Security.salt') для каждого пользователя.

Я знаю, что CakePHP 2.x больше не хэширует пароли автоматически. Это позволяет мне выполнять проверку модели на паролях, что очень приятно. Однако я не вижу способа, которым я могу переопределить метод "пароль" AuthComponent. Поэтому, хотя я могу контролировать, как пароли хэшируются до их сохранения в базе данных, я не могу контролировать, как пароли хэшируются при выполнении фактического входа. Из поваренной книги:

Вам не нужны хэш-пароли перед вызовом $this->Auth->login().

Что я могу сделать, чтобы $this->Auth->login() использовал специальный метод хэширования паролей?

Спасибо.

ОБНОВЛЕНИЕ: Я закончил с ответом доктора Ханнибала Лектера (создание пользовательского объекта аутентификации). Вот как это сделать:

Старый код:

$this->Auth->authenticate = array('Form' => array('fields' => array('username' => 'email')));

Новый код (измените "Форма" на "Пользовательский" ):

$this->Auth->authenticate = array('Custom' => array('fields' => array('username' => 'email')));

Создайте "app/Controller/Component/Auth/CustomAuthenticate.php" и сделайте так:

<?php
App::uses('FormAuthenticate', 'Controller/Component/Auth');

class CustomAuthenticate extends FormAuthenticate {
}

Скопируйте методы "_findUser" и "_password" из "lib/Cake/Controller/Component/Auth/BaseAuthenticate.php" и вставьте их в класс "CustomAuthenticate". Затем выполните следующие две модификации метода "_index.ser":

  • Удалите эту строку из массива "$ conditions": $model . '.' . $fields['password'] => $this->_password($password),

  • Измените if (empty($result) || empty($result[$model])) { на if (empty($result) || empty($result[$model]) || $result[$model][$fields['password']] != $this->_password($password, $result[$model]['id'])) {

Затем выполните следующие две модификации метода "_password":

  • Создайте параметр "$ id", изменив protected function _password($password) { на protected function _password($password, $id) {

  • Обновить значение соли, изменив return Security::hash($password, null, true); на return Security::hash($password, null, Configure::read('Security.salt') . $id);

Наконец, обновите все вхождения AuthComponent::password, чтобы использовать Security::hash с той же логикой, что и выше.

Ответ 2

Считаете ли вы, что вы не используете вызов Auth- > login(), а используете код из текущей реализации вашей модели? (http://api20.cakephp.org/view_source/auth-component#line-506). Вы можете переписать это в соответствии с вашими потребностями.

Ответ 3

Для тех, кто хочет получить дополнительную информацию о том, почему солить каждый пароль - правильный путь к хэш-паролям (примеры кода), посетите здесь: http://crackstation.net/hashing-security.htm.

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

В представленной здесь реализации используется комбинация оригинальной статической соли с твердой кодировкой Auth плюс идентификатор пользователя в качестве соли, что означает, что одна и та же соль повторно используется для каждого пользователя при каждом изменении пароля. Поэтому, если вы хотите следовать рекомендациям этого хэширования, вам нужно генерировать новую случайную соль каждый раз, когда пользователь создает/изменяет свой пароль и должен хранить эту уникальную соль в таблице пользователей вместе с хешированным паролем.

Вы можете использовать свой генератор случайных солей:

define("PBKDF2_SALT_BYTES", 24);
$salt = base64_encode(mcrypt_create_iv(PBKDF2_SALT_BYTES, MCRYPT_DEV_URANDOM));

и, условно, сохраните его в таблице пользователей в новом поле с именем "соль". Поскольку код уже дает вам идентификатор пользователя, вы всегда можете хранить/искать соль по мере необходимости.

Также упоминается в статье раздел "Медленные функции хеширования" с использованием метода, известного как "растяжение ключа" и как реализовать с использованием стандартного алгоритма, такого как PBKDF2 или bcrypt. Приводятся примеры кода PHP, которые можно скопировать и вставить в пользовательскую реализацию Auth для дополнительной безопасности.

Разработчик CakePHP Марк Стори опубликовал запись в блоге о том, как реализовать bcrypt в CakePHP Auth

В разделе комментариев Mark Story прокомментировал, что CakePHP 2.3 будет иметь некоторые новые встроенные функции для генерации хэшей bcrypt.

Ответ 4

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

Вы также можете просто изменить соль в функции beforeSave() в модели User, используя Configure:: write ( "Security.salt", $superAwesomeUserSpecificSalt);