D. Gillard
D. Gillard

Reputation: 63

Symfony 4 EasyAdmin how to encrypt passwords?

I am using EasyAdmin to add/edit users and wanted to ask if there is a possibility of encrypting your passwords? Password encryption worked previously when I used the Symfony 4 make:registration-form but I can't use that now, I have to use EasyAdmin.

easy_admin.yaml

easy_admin:
   entities:
      User:
         class: App\Entity\User
         password_encoding: { algorithm: 'bcrypt', cost: 12 }

Actually, I go to EasyAdmin page (/admin), click User, Add User, fill in email ([email protected]) and password (test), click Save Changes.

Now the user is stored in the database but with plaintext password. enter image description here

(Expected) All of the above but password is encrypted.

Upvotes: 4

Views: 12782

Answers (3)

Dmitriy Atamaniuc
Dmitriy Atamaniuc

Reputation: 83

Code from my working project based on Symfony 5 and PHP 7.4

  1. Extend EasyAdminController:
<?php

declare(strict_types=1);

namespace App\Controller;

use App\Entity\User;
use EasyCorp\Bundle\EasyAdminBundle\Controller\EasyAdminController;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;

/**
 * Class AdminController.
 *
 * @author Dmitriy Atamaniuc <[email protected]>
 */
final class AdminController extends EasyAdminController
{
    private UserPasswordEncoderInterface $encoder;

    private function setUserPlainPassword(User $user): void
    {
        if ($user->getPlainPassword()) {
            $user->setPassword($this->encoder->encodePassword($user, $user->getPlainPassword()));
        }
    }

    /**
     * @required
     */
    public function setEncoder(UserPasswordEncoderInterface $encoder): void
    {
        $this->encoder = $encoder;
    }

    public function persistUserEntity(User $user): void
    {
        $this->setUserPlainPassword($user);

        $this->persistEntity($user);
    }

    public function updateUserEntity(User $user): void
    {
        $this->setUserPlainPassword($user);

        $this->updateEntity($user);
    }
}
  1. Register your controller in EasyAdminBundle, edit config/routes/easy_admin.yaml:
easy_admin_bundle:
    resource: 'App\Controller\AdminController'
    prefix: /admin
    type: annotation
  1. Add plainPassword "virtual" property to your User entity:
/**
* @Assert\NotBlank()
* @Assert\Length(min=5, max=128)
*/
private ?string $plainPassword = null;

public function getPlainPassword(): ?string
{
    return $this->plainPassword;
}

public function setPlainPassword(string $password): void
{
    $this->plainPassword = $password;
}
  1. Update easy_admin.yaml
easy_admin:
    entities:
        User:
            class: App\Entity\User
            label: label.user
            new:
                title:  field.user.add_new
                fields:
                    # some fields like username here
                    - { property: username, label: field.user.username }
                    - { property: fullname, label: field.user.fullname, type: 'text' }
                    # plain password 
                    - { property: plainPassword, label: field.user.password, type: 'password' }

Upvotes: 6

raphox
raphox

Reputation: 119

New version compatible with Symfony 5:

<?php

namespace App\Controller;

use App\Entity\User;
use Symfony\Component\Security\Core\Encoder\EncoderFactory;
use Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder;
use EasyCorp\Bundle\EasyAdminBundle\Controller\EasyAdminController;

class AdminController extends EasyAdminController
{
    protected function persistUserEntity($user)
    {
        $encodedPassword = $this->encodePassword($user, $user->getPlainPassword());
        $user->setPassword($encodedPassword);

        parent::persistEntity($user);
    }

    protected function updateUserEntity($user)
    {
        $encodedPassword = $this->encodePassword($user, $user->getPlainPassword());
        $user->setPassword($encodedPassword);

        parent::updateEntity($user);
    }

    private function encodePassword($user, $password)
    {
        $passwordEncoderFactory = new EncoderFactory([
            User::class => new MessageDigestPasswordEncoder('sha512', true, 5000)
        ]);

        $encoder = $passwordEncoderFactory->getEncoder($user);

        return $encoder->encodePassword($password, $user->getSalt());
    }
}

Upvotes: 6

and_rest
and_rest

Reputation: 302

Extend EasyAdmin controller and handle User entity. Something like this:

namespace AppBundle\Controller\Admin;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AdminController as BaseAdminController;
use AppBundle\Entity\User;

class AdminController extends BaseAdminController
{
    protected function prePersistUserEntity(User $user)
    {
        $encodedPassword = $this->encodePassword($user, $user->getPassword());
        $user->setPassword($encodedPassword);
    }

    protected function preUpdateUserEntity(User $user)
    {
        if (!$user->getPlainPassword()) {
            return;
        }
        $encodedPassword = $this->encodePassword($user, $user->getPlainPassword());
        $user->setPassword($encodedPassword);
    }

    private function encodePassword($user, $password)
    {
        $passwordEncoderFactory = $this->get('security.encoder_factory');
        $encoder = $passwordEncoderFactory->getEncoder($user);
        return $encoder->encodePassword($password, $user->getSalt());
    }

}

Upvotes: 4

Related Questions