Symfony - 在entityRepository中使用选民

时间:2015-01-15 07:47:48

标签: php symfony

我的问题是:我有一个页面/用户,显示所有用户的列表。该页面仅对登录的用户可见,并且根据当前登录用户的用户类型,他只看到列表的一部分。 我认为选民会很好地解决这个问题(如果有更好的选择请告诉我),但是我遇到了supportClass的问题。 用户列表是UserRepository中名为getAllUsers的查询,我尝试将securityContext传递给存储库,以便查询当前用户是否具有访问权限。 我的行为如下:

    public function listAction($limit = 50, $offset = 0) {
        $manager = $this->getDoctrine()->getManager();
        $userRepository = $manager->getRepository('SeamUserBundle:User');
        $users = $userRepository->getAllUsers($this->get('security.context'));
        return ....
    }

在userRepository中我尝试了这个:

public function getAllUsers($securityContext) {
    ....         
    if(!$securityContext->isGranted('USER_LIST_ALL', null)) {
       //modify query
    }
    ...
}

但是如果我将null作为第二个参数传递给isGranted,则$ class现在是Voter,因此supportsClass返回false。 我这样做是错误的吗?如果是这样 - 我该怎么做?如果不是 - 缺少什么?如何将用户实体传递给isGranted?

提前致谢。

1 个答案:

答案 0 :(得分:1)

要在全球范围内授予权限,您希望使用roles代替voters

角色与选民之间的差异:

选民可以告诉用户是否可以对对象执行操作(关系user-action-instance_of_object)。选民背后的逻辑取决于你。你需要实现它们,symfony只找到选民并收集他们的决定。示例:用户可以编辑文章的特定实例。

角色可以告诉用户是否具有全局权限(关系用户 - 操作)。角色背后的逻辑由symfony处理。您只需在$ securityContext上向用户添加角色并需要角色。示例:用户可以撰写新文章。

列出所有用户都基于用户可以做什么,因此它是角色的工作。您需要将角色ROLE_USER_LIST_ALL添加到允许列出所有用户的用户。您可能应该在用户登录时在UserProvider中执行此操作。您需要做的只是UserInterface需要实现getRoles。有关在数据库中定义角色的一些信息可以在symfony docs

中找到

然后在UserRepository电话

$securityContext->isGranted('ROLE_USER_LIST_ALL');

请注意,没有第二个参数,因为它是与特定对象实例无关的全局权限。

将安全上下文作为getter的参数传递也是不理想的。相反,将存储库指定为服务并设置安全上下文可能是个好主意。

services:
   seam.user.repository:
    class: Seam\UserBundle\UserRepository
    factory_service: doctrine.orm.entity_manager
    factory_method: getRepository
    arguments:
      - Seam\UserBundle\User
    calls:
      - [ setSecurityContext, [@security.context] ]

然后你可以用

检索它
$container->get('seam.user.repository); 
//in controler use $this instead of $container

(您需要在setSecurityContext课程中实施UserRepository