我的问题是:我有一个页面/用户,显示所有用户的列表。该页面仅对登录的用户可见,并且根据当前登录用户的用户类型,他只看到列表的一部分。 我认为选民会很好地解决这个问题(如果有更好的选择请告诉我),但是我遇到了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?
提前致谢。
答案 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
)