password granted annotation forms security symfony doctrine2

forms - granted - symfony login roles



Implementar cambio de contraseƱa en Symfony2 (5)

¿Cuál es la mejor manera de implementar la funcionalidad de cambio de contraseña en Symfony2? Ahora mismo estoy usando esto:

$builder->add(''password'', ''repeated'', array( ''first_name'' => ''New password'', ''second_name'' => ''Confirm new password'', ''type'' => ''password'' ));

También debe contener la verificación de la contraseña actual por razones de seguridad.

Nota : no estoy usando FOSUserBundle .


¿No puede obtener una contraseña antigua del usuario antes de enlazar el formulario?

// in action: $oldpassword = $user->getPassword(); if ($request->getMethod() == ''POST'') { $form->bindRequest($request); if ($form->isValid()) { // check password here (by hashing new one)


Desde Symfony 2.3 puedes usar fácilmente la restricción de validación de UserPassword .

Acme / UserBundle / Form / Model / ChangePassword.php

namespace Acme/UserBundle/Form/Model; use Symfony/Component/Security/Core/Validator/Constraints as SecurityAssert; use Symfony/Component/Validator/Constraints as Assert; class ChangePassword { /** * @SecurityAssert/UserPassword( * message = "Wrong value for your current password" * ) */ protected $oldPassword; /** * @Assert/Length( * min = 6, * minMessage = "Password should by at least 6 chars long" * ) */ protected $newPassword; }

Acme / UserBundle / Form / ChangePasswordType.php

namespace Acme/UserBundle/Form; use Symfony/Component/Form/AbstractType; use Symfony/Component/Form/FormBuilderInterface; use Symfony/Component/OptionsResolver/OptionsResolverInterface; class ChangePasswordType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add(''oldPassword'', ''password''); $builder->add(''newPassword'', ''repeated'', array( ''type'' => ''password'', ''invalid_message'' => ''The password fields must match.'', ''required'' => true, ''first_options'' => array(''label'' => ''Password''), ''second_options'' => array(''label'' => ''Repeat Password''), )); } public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults(array( ''data_class'' => ''Acme/UserBundle/Form/Model/ChangePassword'', )); } public function getName() { return ''change_passwd''; } }

Acme / UserBundle / Controller / DemoController.php

namespace Acme/UserBundle/Controller; use Symfony/Bundle/FrameworkBundle/Controller/Controller; use Symfony/Component/HttpFoundation/Request; use Acme/UserBundle/Form/ChangePasswordType; use Acme/UserBundle/Form/Model/ChangePassword; class DemoController extends Controller { public function changePasswdAction(Request $request) { $changePasswordModel = new ChangePassword(); $form = $this->createForm(new ChangePasswordType(), $changePasswordModel); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { // perform some action, // such as encoding with MessageDigestPasswordEncoder and persist return $this->redirect($this->generateUrl(''change_passwd_success'')); } return $this->render(''AcmeUserBundle:Demo:changePasswd.html.twig'', array( ''form'' => $form->createView(), )); } }


Solo agregue esto a su tipo de formulario:

$builder->add(''oldPlainPassword'', /Symfony/Component/Form/Extension/Core/Type/PasswordType::class, array( ''constraints'' => array( new /Symfony/Component/Security/Core/Validator/Constraints/UserPassword(), ), ''mapped'' => false, ''required'' => true, ''label'' => ''Current Password'', ));


Tienes que crear otro modelo con dos campos:

  • uno para la contraseña actual;
  • y el otro por el nuevo.

O agregue una propiedad no persistente a su modelo de usuario como lo hace FOSUserBundle (vea la propiedad plainPassword ).

Por lo tanto, una vez que haya verificado que la contraseña actual y la nueva son válidas, codifique la nueva contraseña y reemplace la antigua con esta.


Utilizo una acción desde mi controlador:

public function changepasswordAction(Request $request) { $session = $request->getSession(); if($request->getMethod() == ''POST'') { $old_pwd = $request->get(''old_password''); $new_pwd = $request->get(''new_password''); $user = $this->getUser(); $encoder = $this->container->get(''security.encoder_factory'')->getEncoder($user); $old_pwd_encoded = $encoder->encodePassword($old_pwd, $user->getSalt()); if($user->getPassword() != $old_pwd_encoded) { $session->getFlashBag()->set(''error_msg'', "Wrong old password!"); } else { $new_pwd_encoded = $encoder->encodePassword($new_pwd, $user->getSalt()); $user->setPassword($new_pwd_encoded); $manager = $this->getDoctrine()->getManager(); $manager->persist($user); $manager->flush(); $session->getFlashBag()->set(''success_msg'', "Password change successfully!"); } return $this->render(''@adminlte/profile/change_password.html.twig''); } return $this->render(''@adminlte/profile/change_password.html.twig'', array( )); }