Đây là câu trả lời chi tiết. Cảm ơn Manu vì bàn đạp!
Trước tiên, hãy chắc chắn để có được những FOSUserBundle đúng trong file composer.json ("dev-master", KHÔNG "*"):
"friendsofsymfony/user-bundle":"dev-master"
Sau đây là tất cả chứa trong bó sử dụng của riêng tôi, mở rộng FOSUserBundle theo hướng dẫn trong tài liệu cài đặt.
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));
}
}
Vấn đề với FOSUserBundle không thực sự đảm bảo rằng người dùng thay đổi mật khẩu là một vấn đề cho một ngày khác.
Tôi hy vọng điều này sẽ giúp ai đó.
Bạn có thể cụ thể hơn không? Có rất nhiều cách tiếp cận để giải quyết vấn đề này. Đăng mã của bạn sẽ giúp chúng tôi xác định cách tiếp tục. Dù sao, việc sử dụng nhiều vai trò hơn cờ, có thể là một ý tưởng hay vì bạn có thể quản lý nó bằng tường lửa symfony. Do đó, những người có vai trò CREDENTIAL_EXPIRED, không thể truy cập toàn bộ web và họ bị mắc kẹt dưới dạng buộc họ phải thay đổi mật khẩu của mình. – Manu
Mã sẽ là FOSUserBundle. Vai trò là một ý tưởng tuyệt vời vì nó sẽ không đòi hỏi các lớp mở rộng. Tôi sẽ cho một phát bắn. Cảm ơn. – David