Symfony - 在 entityRepository 中使用投票器
Symfony - use voter in entityRepository
我的问题是:我有一个页面 /user,其中显示了所有用户的列表。该页面仅对已登录的用户可见,并且根据当前登录用户的用户类型,他只能看到列表的一部分。
我认为投票器将是一个很好的解决方案(如果有更好的解决方案请告诉我),但我对 supportsClass 有疑问。
用户列表是 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 现在是投票者,因此 supportsClass returns false。
我做错了吗?如果是这样 - 我该怎么做?如果没有-缺少什么?如何将用户实体传递给 isGranted?
提前致谢。
要在全局基础上授予您要使用的权限 roles instead of voters。
角色与选民的区别:
投票者 会告诉 用户是否可以对对象 (关系 user-action-instance_of_object)执行操作。选民背后的逻辑取决于你。您需要实施它们,而 symfony 只会找到投票者并收集他们的决定。示例:用户可以编辑文章的特定实例。
角色 告诉用户是否拥有全局权限(关系用户操作)。角色背后的逻辑由 symfony 处理。您只需向用户添加角色并在 $securityContext 上需要角色。示例:用户可以撰写新文章。
列出所有用户是基于用户可以做什么,因此这是角色的工作。您需要将角色 ROLE_USER_LIST_ALL
添加到允许列出所有用户的用户。当用户登录时,您可能应该在 UserProvider 中执行此操作。您需要做的就是 UserInterface requires implement getRoles. Some information about defining roles in database can be found in 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
(您需要在 UserRepository
class 中实施 setSecurityContext
)
我的问题是:我有一个页面 /user,其中显示了所有用户的列表。该页面仅对已登录的用户可见,并且根据当前登录用户的用户类型,他只能看到列表的一部分。 我认为投票器将是一个很好的解决方案(如果有更好的解决方案请告诉我),但我对 supportsClass 有疑问。 用户列表是 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 现在是投票者,因此 supportsClass returns false。 我做错了吗?如果是这样 - 我该怎么做?如果没有-缺少什么?如何将用户实体传递给 isGranted?
提前致谢。
要在全局基础上授予您要使用的权限 roles instead of voters。
角色与选民的区别:
投票者 会告诉 用户是否可以对对象 (关系 user-action-instance_of_object)执行操作。选民背后的逻辑取决于你。您需要实施它们,而 symfony 只会找到投票者并收集他们的决定。示例:用户可以编辑文章的特定实例。
角色 告诉用户是否拥有全局权限(关系用户操作)。角色背后的逻辑由 symfony 处理。您只需向用户添加角色并在 $securityContext 上需要角色。示例:用户可以撰写新文章。
列出所有用户是基于用户可以做什么,因此这是角色的工作。您需要将角色 ROLE_USER_LIST_ALL
添加到允许列出所有用户的用户。当用户登录时,您可能应该在 UserProvider 中执行此操作。您需要做的就是 UserInterface requires implement getRoles. Some information about defining roles in database can be found in 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
(您需要在 UserRepository
class 中实施 setSecurityContext
)