【问题标题】:How to a dynamically add roles to a user?如何为用户动态添加角色?
【发布时间】:2014-07-16 21:04:01
【问题描述】:

当用户登录时,无论是第一次登录还是通过存在的 cookie,我想根据我运行的一些查询的结果为他们分配一个或多个额外的用户角色。

我想我需要创建一个事件侦听器来注入安全组件和实体管理器,这样我就可以运行我的查询并向当前用户添加角色。

我不太确定这是否可以通过事件来实现,因为在授权完成之前,但在身份验证之后,需要在防火墙上下文中触发事件。

我确实看到了this existing question,但我无法让它发挥作用(在事件运行后角色实际上并没有被识别)。

是否可以使用事件侦听器来做到这一点?

我认为我的替代方法是在 User 实体上使用加载后生命周期回调并在那里运行一些查询,但这似乎不对。

【问题讨论】:

  • 你使用 FOSUserBundle 吗?
  • 我没有,我只是在使用我自己的教义entity provider。 FOSUserBundle 的功能比我需要的多得多(不需要注册、忘记密码等)

标签: symfony symfony-2.4


【解决方案1】:

您可以在内核上创建一个事件监听器。它会在每次加载页面时运行。

它将检查他们是否是登录用户,然后您可以执行一些自定义逻辑来查看您是否需要更新他们的角色,如果您需要更新它,则使用新设置登录他们,然后他们会继续以他们的新角色在系统中。

我没有测试过这段代码,所以它可能有一些错误。

services.yml

bundle.eventlistener.roles:
    class: Sample\MyBundle\EventListener\Roles
    arguments: [@service_container, @security.context]
    tags:
        - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }

监听器\Roles.php

namespace Sample\MyBundle\EventListener;

use Symfony\Component\DependencyInjection\ContainerInterface as Container;
use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;

use Sample\MyBundle\Entity\Users; //Your USER entity

class Roles {
    private $container;
    private $context;

    public function __construct(Container $container, SecurityContext $context) {
        $this->container = $container;
        $this->context = $context;
    }

    public function onKernelController(FilterControllerEvent $event) {
        if($this->context->getToken()->getUser() instanceof Users) {

            //Custom logic to see if you need to update the role or not.

            $user = $this->context->getToken()->getUser();

            //Update your roles
            $user->setRole('ROLE_WHATEVER');

            $em = $this->container->get('doctrine')->getManager();
            $em->persist($user);
            $em->flush();

            //Create new user token
            //main == firewall setting
            $token = new UsernamePasswordToken($user, $user->getPassword(), 'main', $user->getRoles());

            $this->context->setToken($token);
        }
    }
}

【讨论】:

  • 谢谢,我会尝试使用这种方法。我使用的是this SSO bundle,它有一个更复杂的令牌,所以动态创建一个新令牌并不容易
  • 祝你好运,我以前没有使用过那个包,所以我不确定正确的语法是什么。
猜你喜欢
  • 2012-02-11
  • 1970-01-01
  • 2013-11-11
  • 1970-01-01
  • 1970-01-01
  • 2021-03-22
  • 2022-01-18
  • 2019-08-11
  • 1970-01-01
相关资源
最近更新 更多