我在Symfony 2.8项目中工作,我对用户/组/角色|权限有疑问。有几种方法可以处理用户和组,例如SonataUser和SonataAdmin之上的EasyAdmin,但所有这些方法都缺乏ROLE |权限管理,这正是我的疑问:什么& #39;是处理它们的正确方法吗?是的,我知道我需要在security.yml
写一下,但我不知道我是否可以在DB(某处)存储然后从那里读取。我对此进行了研究,发现了ACL,Voters等等,但我没有清楚自己的想法,研究让我很困惑,所以我需要一些来自这里的人。然后:
更新:改进问题
我想要的是ManyToMany
和users
以及可能roles
和groups
之间的roles
关系。我认为,当SonataUserBundle
处理时,可以在roles
表格中创建一个列user
,并为每个用户分配很多角色,如果我没有弄错的话,甚至可以创建新的角色但是,如果我想创建尽可能多的角色而不将它们分配给用户,然后将更多角色添加到用户甚至添加到组中呢?
你会怎么做?
答案 0 :(得分:2)
您可以随时随地在FOSUserBundle
添加新角色。您无需先将其添加到security.yml
文件中。
要做到这一点,你可以这样做:
$user = new User();
$user->addRole('ROLE_NEWUSER'); //Role Name should begin with 'ROLE_'
或在您的控制器中,您可以获得当前用户或任何用户
$this->getUser();
$user->addRole('ROLE_NEWUSER'); //Role Name should begin with 'ROLE_'
这回答了你的第一和第二部分。
对于第三部分,Roles 可以用作权限。我之前已经实现了一个结构,我根据用户角色限制对页面的访问,同时根据角色限制他们可以更改的数据。
UPDATE 我为此实现了一个Event Listener,它将侦听所有称为onKernelRequest
的内核请求。我已经部分完成了SQL端的访问管理,因为我的角色也存储在SQL端,但是在服务器端可以做同样的事情。我的事件监听器看起来像这样:(这是我所拥有的精简版)
class TokenListener
{
protected $em;
protected $token_storage;
protected $templating;
protected $router;
protected $resolver;
public function __construct($em,TokenStorageInterface $token_storage, TwigEngine $templating, Router $router, ControllerResolver $resolver)
{
$this->em = $em;
$this->token_storage = $token_storage;
$this->templating = $templating;
$this->router = $router;
$this->resolver = $resolver;
}
public function onKernelRequest(GetResponseEvent $event)
{
$request = $event->getRequest();
$route = $request->attributes->get('_route');
$routeArr = array('fos_js_routing_js', 'fos_user_security_login', '_wdt'); //These are excluded routes. These are always allowed. Required for login page
if(!is_int(array_search($route, $routeArr)) && false)
{
$userRoles = $this->token_storage->getToken()->getUser()->getRoles();
if(!in_array('ROLE_NEWUSER', $userRoles))
{
$event->setResponse(new RedirectResponse($this->router->generate('user_management_unauthorized_user', array())));
}
}
}
}
我的services.yml看起来像这样
services:
app.tokens.action_listener:
class: EventListenerBundle\EventListener\TokenListener
arguments:
entityManager: "@doctrine.orm.entity_manager"
token_storage: "@security.token_storage"
templating: "@templating"
router: "@router"
resolver: "@controller_resolver"
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
更新要回答问题的更新部分,您可以做的是拥有另一个roles
实体,您可以提前填充所需的角色,然后进行一对多与原始User
表的关系。然后,如果角色实体中已存在角色,则可以在添加新内容时检查prePersist or preUpdate Doctrine Lifecycle Events
之类的内容。那应该可以解决你的问题。所有这些都将涉及一些调整。没有直接的方法可以做到这一点。
答案 1 :(得分:0)
这取决于你想要如何实现它。
一种方法:
将UserProviderInterface
实施为loadByUsername
(这是您加载角色和权限的位置)UserInterface
(您的User
)的实现。
然后实施VoterInterface
。将此注册为标记为security.voter
的服务,并将其指定为security.yml中的提供程序。覆盖vote
函数,以评估User
您从TokenInterface
获取的权限(也可能是角色),这是该函数的第一个参数。