0
votes

Using Symfony2, Sonata Admin and mongodb, the application save the fields but the password is not encrypted.

The CRUD work very fine saving the User fields on database, the problem is when loggin i got "Bad Credentials", and when i see the database the password is not encrypted.

I am not using UserBundle,FOSUserBundle.

  1. UserAdmin.php

    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
        ->add('names', null, array('label' => 'Nombres','required' => true))
        ->add('surnames', null, array('label' => 'Apellidos'))
        ->add('email', 'email', array('label' => 'Email','required' => true))
        ->add('password', 'repeated', array('type' => 'password',
                            'first_options' => array('label' => 'Contraseña'),
                            'second_options' => array('label' => 'Repita la contraseña'),
                            'invalid_message' => 'Las contraseñas no coinciden'
                            ))
        ->add('birthday','date', array('label' => 'Fecha de Nacimiento',
                      'years' => range(date('y'),date('Y')-90),
                      'format' => 'dd-MMMM-yyyy'
                      ));
    }
    
  2. security.yml

    security:
        encoders:
        Bluetton\DispatcherBundle\Document\User:
          algorithm: sha512
          encode-as-base64: true
          iterations: 10
    
        role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
    
        providers:
        dispatcherdb:
            mongodb: { class: Bluetton\DispatcherBundle\Document\User, property: email }
    
        firewalls:
        main:
            pattern: /.*
            provider: dispatcherdb
            form_login:
            login_path: /login
            check_path: /login_check
            remember_me: true
            logout:
            path: /logout
            target: /
            remember_me:
            key: MiClaveSegura
            lifetime: 1800
            path: /.*
            domain: ~
            security: true
            anonymous: true
        access_control:
        - { path: /setup, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: /login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: /user, roles: IS_AUTHENTICATED_ANONYMOUSLY } #ROLE_USER } #
        - { path: /.*, roles: IS_AUTHENTICATED_ANONYMOUSLY }
    
  3. SecurityController.php

    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('DispatcherBundle:Security:login.html.twig', array(
                // last username entered by the user
                'last_username' => $session->get(SecurityContext::LAST_USERNAME),
                'error'         => $error,
            ));
        }
        public function indexAction()
        {
            $user = new User();
    
            $validator = $this->get('validator');
            $errors = $validator->validate($user);
    
            if (count($errors) > 0) {
    
                $errorsString = (string) $errors;
    
                return new Response($errorsString);
            }
    
            return new Response('El usuario es valido!');
        }
    }
    
2

2 Answers

0
votes

I solve the problem overriding the functions preUpdate() and prePersist() on UserAdmin class

            public function preUpdate($object) {
                $uniqid = $this->getRequest()->query->get('uniqid');
                $encoder = new MessageDigestPasswordEncoder('sha512', true, 10);
                $formData = $this->getRequest()->request->get($uniqid);
                if(array_key_exists('password', $formData) && $formData['password'] !== null && strlen($formData['password']['first' ]) > 0) {
                    $object->setPassword($encoder->encodePassword($formData['password']['first' ],$object->getSalt()));
                }
            }

            public function prePersist($object) {
                $encoder = new MessageDigestPasswordEncoder('sha512', true, 10);
                $uniqid = $this->getRequest()->query->get('uniqid');
                $formData = $this->getRequest()->request->get($uniqid);
                if(array_key_exists('password', $formData) && $formData['password'] !== null && strlen($formData['password']['first' ]) > 0) {
                    $object->setPassword($encoder->encodePassword($formData['password']['first' ],$object->getSalt()));
                }
            }
0
votes
  1. you should use hooks as described there (your case for sure)
  2. you need to change field declaration to something like that (use plainPassword instead of password)

    ->add('plainPassword', 'repeated', array(
        'type' => 'password',
        'options' => array('translation_domain' => 'FOSUserBundle'),
        'first_options' => array('label' => 'form.password'),
        'second_options' => array('label' => 'form.password_confirmation'),
        'invalid_message' => 'fos_user.password.mismatch',
    ))