gpt4 book ai didi

symfony - 如何使用 FOSUserBundle 强制更改密码?

转载 作者:行者123 更新时间:2023-12-03 14:36:06 25 4
gpt4 key购买 nike

我正在尝试在 Symfony 2.1 项目中实现安全功能,管理员可以在其中使用初始密码创建用户,然后在用户第一次登录时自动触发更改密码处理程序。

我在覆盖 FOSUserBundle 类时遇到了问题,我想这肯定已经以某种方式内置了,至少部分内置了,尽管我在任何地方的文档中都看不到它。

我想在实体中使用credentials_expired 标志。当管理员创建用户时,这将被设置为 1。当用户第一次登录时,credentials_expired 被检查,而不是抛出异常,而是触发更改密码。我已经做到了这一步。

然后,ChangePasswordController 将确保密码实际上已更改(这似乎不是 FOS 中的默认行为)并且将 credentials_expired 设置为 0。这就是我被卡住的地方。有很多层次的服务,我似乎无法正确定制。

最佳答案

这是详细的答案。感谢 Manu 的跳板!

首先,确保在 composer.json 文件中获得正确的 FOSUserBundle(“dev-master”,而不是“*”):

"friendsofsymfony/user-bundle":"dev-master"

以下全部包含在我自己的用户包中,它按照安装文档中的说明扩展了 FOSUserBundle。

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));
}
}

FOSUserBundle 的问题实际上并没有确保用户更改密码是另一天的问题。

我希望这可以帮助某人。

关于symfony - 如何使用 FOSUserBundle 强制更改密码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15256759/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com