Ecco la risposta dettagliata. Grazie Manu per il trampolino di lancio!
prima cosa, assicurarsi di ottenere il corretto FOSUserBundle nel file composer.json ("dev-master", non "*"):
"friendsofsymfony/user-bundle":"dev-master"
Il seguente è tutto contenuto nel mio fagotto utente, che estende FOSUserBundle come indicato nel documento di installazione.
PortalFlare/Bundle/UserBundle/Resources/config/services.xml:
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="portal_flare_user.forcepasswordchange.class">PortalFlare\Bundle\UserBundle\EventListener\ForcePasswordChange</parameter>
<parameter key="portal_flare_user.passwordchangelistener.class">PortalFlare\Bundle\UserBundle\EventListener\PasswordChangeListener</parameter>
</parameters>
<services>
<service id="portal_flare_user.forcepasswordchange" class="%portal_flare_user.forcepasswordchange.class%">
<argument type="service" id="router" />
<argument type="service" id="security.context" />
<argument type="service" id="session" />
<tag name="kernel.event_listener" event="kernel.request" method="onCheckStatus" priority="1" />
</service>
<service id="portal_flare_user.passwordchange" class="%portal_flare_user.passwordchangelistener.class%">
<argument type="service" id="router" />
<argument type="service" id="security.context" />
<argument type="service" id="fos_user.user_manager" />
<tag name="kernel.event_subscriber" />
</service>
</services>
</container>
PortalFlare/Bundle/UserBundle/EventListener/ForcePasswordChange.php:
<?php
namespace PortalFlare\Bundle\UserBundle\EventListener;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Bundle\FrameworkBundle\Routing\Router;
use Symfony\Component\HttpFoundation\Session\Session;
/**
* @Service("request.set_messages_count_listener")
*
*/
class ForcePasswordChange {
private $security_context;
private $router;
private $session;
public function __construct(Router $router, SecurityContext $security_context, Session $session) {
$this->security_context = $security_context;
$this->router = $router;
$this->session = $session;
}
public function onCheckStatus(GetResponseEvent $event) {
if (($this->security_context->getToken()) && ($this->security_context->isGranted('IS_AUTHENTICATED_FULLY'))) {
$route_name = $event->getRequest()->get('_route');
if ($route_name != 'fos_user_change_password') {
if ($this->security_context->getToken()->getUser()->hasRole('ROLE_FORCEPASSWORDCHANGE')) {
$response = new RedirectResponse($this->router->generate('fos_user_change_password'));
$this->session->setFlash('notice', "Your password has expired. Please change it.");
$event->setResponse($response);
}
}
}
}
}
PortalFlare/Bundle/UserBundle/EventListener/PasswordChangeListener.php:
<?php
namespace PortalFlare\Bundle\UserBundle\EventListener;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Event\FormEvent;
use FOS\UserBundle\Doctrine\UserManager;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\SecurityContext;
/**
* Listener responsible to change the redirection at the end of the password change
*/
class PasswordChangeListener implements EventSubscriberInterface {
private $security_context;
private $router;
private $usermanager;
public function __construct(UrlGeneratorInterface $router, SecurityContext $security_context, UserManager $usermanager) {
$this->security_context = $security_context;
$this->router = $router;
$this->usermanager = $usermanager;
}
/**
* {@inheritDoc}
*/
public static function getSubscribedEvents() {
return array(
FOSUserEvents::CHANGE_PASSWORD_SUCCESS => 'onChangePasswordSuccess',
);
}
public function onChangePasswordSuccess(FormEvent $event) {
$user = $this->security_context->getToken()->getUser();
$user->removeRole('ROLE_FORCEPASSWORDCHANGE');
$this->usermanager->updateUser($user);
$url = $this->router->generate('_welcome');
$event->setResponse(new RedirectResponse($url));
}
}
Il problema con FOSUserBundle che in realtà non si assicura che l'utente cambi la password è un problema per un altro giorno.
Spero che questo aiuti qualcuno.
Potrebbe essere più specifico? Ci sono molti approcci per risolverlo. Pubblicare il tuo codice ci aiuterà a identificare come procedere. Ad ogni modo, usare ruoli più probabili dei flag, potrebbe essere una buona idea, perché puoi gestirlo con il firewall di symfony. Pertanto, le persone che hanno il ruolo CREDENTIAL_EXPIRED, non possono accedere all'intero web e sono bloccate in un modulo che le costringe a cambiare la password. – Manu
Il codice sarebbe FOSUserBundle. Il ruolo è una grande idea in quanto non richiederebbe l'estensione delle lezioni. Darò un colpo. Grazie. – David