Symfony2 создает собственный кодер для хранения пароля
Я новичок в Symfony2, и у меня есть простой вопрос о кодировании паролей пользователей в моей БД.
Я хотел бы закодировать и сохранить в базе данных моего пользователя пароль таким образом:
encoded_password = salt . sha1 ( salt . raw_password )
Я нашел различные кодировщики (sha1, sha512, plaintext), я увидел, что с открытым текстом у меня в моем DB raw_password {salt}, но мне все еще не нравится метод signin/login/getSalt() в Symfony2.
Если бы вы могли поднять меня на это (пожалуйста, предположите, что я не хочу использовать существующий пакет для UserManagement, я бы хотел сделать свой собственный), это было бы УДИВИТЕЛЬНО!
Спасибо
EDIT:
Я мог бы сделать это в своем signinAction():
$salt = substr(md5(time()),0,10);
$pwd = $encoder->encodePassword($user->getPassword(), $salt);
$user->setPassword($salt.$pwd);
Я мог бы сделать это в моем getSalt():
return substr($this->password,0,10);
Но в настоящее время у меня есть только это в моем loginAction(): (см. здесь: http://symfony.com/doc/current/book/security.html)
// src/Acme/SecurityBundle/Controller/Main;
namespace Acme\SecurityBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Core\SecurityContext;
class SecurityController extends Controller
{
public function loginAction()
{
$request = $this->getRequest();
$session = $request->getSession();
// get the login error if there is one
if ($request->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) {
$error = $request->attributes->get(SecurityContext::AUTHENTICATION_ERROR);
} else {
$error = $session->get(SecurityContext::AUTHENTICATION_ERROR);
}
return $this->render('AcmeSecurityBundle:Security:login.html.twig', array(
// last username entered by the user
'last_username' => $session->get(SecurityContext::LAST_USERNAME),
'error' => $error,
));
}
}
Как я могу сказать Symfony2 проверить пароль во время действия входа так, как мне нужно? (curently делать encode (пароль, соль) и не salt.encode(пароль, соль)
Ответы
Ответ 1
Чтобы сделать его простым: вы должны создать и добавить новый Service, добавить его в свой комплект и спецификацию, чтобы User
класс будет использовать его. Сначала вы должны реализовать свой собственный парольный кодер:
namespace Acme\TestBundle\Service;
use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface;
class Sha256Salted implements PasswordEncoderInterface
{
public function encodePassword($raw, $salt)
{
return hash('sha256', $salt . $raw); // Custom function for password encrypt
}
public function isPasswordValid($encoded, $raw, $salt)
{
return $encoded === $this->encodePassword($raw, $salt);
}
}
Затем вы добавите определение службы и хотите указать свой собственный кодер для класса User
. В TestBundle/Resources/config/services.yml вы добавляете настраиваемый кодер:
services:
sha256salted_encoder:
class: Acme\TestBundle\Service\Sha256Salted
а в app/config/security.yml вы можете указать свой собственный класс как кодер по умолчанию (для класса Acme\TestBundle\Entity\User
):
encoders:
Acme\TestBundle\Entity\User:
id: acme.test.sha256salted_encoder
Конечно, соль играет центральную роль в шифровании паролей. Соль уникальна и хранится для каждого пользователя. Класс User
может быть автоматически сгенерирован с использованием аннотаций YAML (таблица должна, конечно же, содержать имя пользователя, пароль, соль и т.д.) И должна реализовывать UserInterface
.
Наконец, вы можете использовать его (код контроллера), когда вам нужно создать новый Acme\TestBundle\Entity\User
:
// Add a new User
$user = new User();
$user->setUsername = 'username';
$user->setSalt(uniqid(mt_rand())); // Unique salt for user
// Set encrypted password
$encoder = $this->container->get('acme.test.sha256salted_encoder')
->getEncoder($user);
$password = $encoder->encodePassword('MyPass', $user->getSalt());
$user->setPassword($password);
Ответ 2
Спасибо, gremo. Там небольшая проблема в последнем фрагменте вашего кода, при использовании сервиса мы должны называть его именем "sha256salted_encoder", а не acme.test.sha256salted_encoder.
кроме того,
// Add a new User
$user = new User();
$user->setUsername = 'username';
$user->setSalt(uniqid(mt_rand())); // Unique salt for user
// Set encrypted password
$encoder = $this->container->get('security.encoder_factory')
->getEncoder($user);
$password = $encoder->encodePassword('MyPass', $user->getSalt());
$user->setPassword($password);
в первую очередь мы будем называть кодировщик безопасности, тогда мы найдем
sha256salted_encoder
и услуга будет полезна.
Все лучшее
Ответ 3
В принципе, вы должны/должны использовать только bcrypt encoder для безопасного хранения пароля в вашей базе данных.
вот почему:
http://dustwell.com/how-to-handle-passwords-bcrypt.html
http://adambard.com/blog/3-wrong-ways-to-store-a-password/
Чтобы настроить этот кодер, вы должны отредактировать файл security.yml
security:
encoders:
Symfony\Component\Security\Core\User\UserInterface: bcrypt
Этот кодер используется внутри класса UserPasswordEncoder
, который можно найти здесь: Symfony\Component\Security\Core\Encoder