如何在 Symfony 中检索完整的角色层次结构
Posted
技术标签:
【中文标题】如何在 Symfony 中检索完整的角色层次结构【英文标题】:How to retrieve full role hierarchy in Symfony 【发布时间】:2012-01-19 14:50:53 【问题描述】:我正在使用 symfony2 角色层次结构,它运行良好,但为了执行一些更改,我必须检索在我的 security.yml
中设置的 role_hierarchy
。
role_hierarchy:
ROLE_USER: [ROLE_ACCESS_USER, ROLE_ACCESS_DATA, ROLE_ACCESS_PRODUCT]
使用getRoles()
只返回ROLE_USER
,我怎么能在我的代码中知道ROLE_USER
是用ROLE_ACCESS_USER, ROLE_ACCESS_DATA, ROLE_ACCESS_PRODUCT
创建的?
感谢您的帮助。
【问题讨论】:
你需要它做什么? 我的“用户”(ROLE_USER)有一组默认的角色,我想允许管理员只给他特定的角色,例如只有 ROLE_ACCESS_DATA。我想通过一个显示所有现有角色的界面来做到这一点。 【参考方案1】:您可以从容器中获取层次结构:
$container->getParameter('security.role_hierarchy.roles')
【讨论】:
【参考方案2】:启用自动连接后,您还可以直接注入填充了全局角色层次结构的RoleHierarchy
对象。
只需使用依赖注入将RoleHierarchyInterface
注入您的控制器或服务:
use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;
public function __construct(RoleHierarchyInterface $roleHierarchy)
$this->roleHierarchy = $roleHierarchy;
注意:这也允许您在 RoleHierarchy
对象上调用 getReachableRoles()
,这在您的情况下可能很有用:
use Symfony\Component\Security\Core\Role\Role;
$this->roleHierarchy->getReachableRoles([new Role('ROLE_USER')])
从 Symfony4 开始,您必须在 config/services.yml
中添加 security.role_hierarchy
的别名,方法是添加以下行:
services:
# creating alias for RoleHierarchyInterface
Symfony\Component\Security\Core\Role\RoleHierarchyInterface: '@security.role_hierarchy'
【讨论】:
使用 Symfony 3.4 - 我也必须使用别名。 别名是在 Symfony 4.1 中添加的,不再需要手动添加:github.com/symfony/symfony/pull/26639 symfony 5 怎么样?【参考方案3】:Symfony 5 回答
namespace App\Controller;
...
use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;
use Symfony\Component\Security\Core\Role\RoleHierarchy;
class UserController extends AbstractController
private $roleHierarchy;
/**
* @Route("/users", name="users")
*/
public function usersIndex(RoleHierarchyInterface $roleHierarchy)
$this->roleHierarchy = $roleHierarchy;
// your user service or your Doctrine code here
$users = ...
foreach ($users as $user)
if ($this->isGranted($user, 'ROLE_SUPER_ADMIN'))
...
...
private function isGranted(User $user, string $role): bool
$reachableRoles = $this->roleHierarchy->getReachableRoleNames($user->getRoles());
foreach ($reachableRoles as $reachableRole)
if ($reachableRole === $role)
return true;
return false;
注意:为了简单起见,我将所有内容都放在了控制器中,但我当然建议将角色管理代码移动到您自己的专用角色服务中。
【讨论】:
$roles = $roleHierarchy->getReachableRoleNames($user->getRoles());
未在 usersIndex()
方法中使用 - 是被遗忘的语句吗?
@long 谢谢,不知道为什么会出现在这里。固定:)
如何在控制器中不提及而用扩展逻辑覆盖RoleHierarchy
接口?【参考方案4】:
为了正确表示您的角色,您需要递归。角色可以扩展其他角色。
这里是一个例子:https://***.com/a/36900807/3635680
【讨论】:
请在您的回答中引用相关文字。不建议发布仅链接的答案(即使链接导致 Stack Overflow)。【参考方案5】:security.role_hierarchy.roles 是security.yml中定义的所有安全角色
如果您想包含 Sonata 管理员角色,您可以检查 SonataUserBundle\Form\Type\SecurityRolesType 中的代码
foreach ($this->pool->getAdminServiceIds() as $id)
try
$admin = $this->pool->getInstance($id);
catch (\Exception $e)
continue;
$securityHandler = $admin->getSecurityHandler();
foreach ($securityHandler->buildSecurityInformation($admin) as $role => $acls)
$roles[$role] = $role;
【讨论】:
以上是关于如何在 Symfony 中检索完整的角色层次结构的主要内容,如果未能解决你的问题,请参考以下文章