Symfony 2.1 - $this->get('security.context')->isGranted('ROLE_ADMIN') 返回 false,即使 Profiler



我有一个控制器操作(控制器通过JMSDiExtraBundle将$this->securityContext设置为$this->get('security.context')):

$user = $this->securityContext->getToken()->getUser();
$groupRepo = $this->getDoctrine()->getRepository('KekRozsakFrontBundle:Group');
if ($this->securityContext->isGranted('ROLE_ADMIN') === false) {
    $myGroups = $groupRepo->findByLeader($user);
} else {
    $myGroups = $groupRepo->findAll();
}

当我登录到dev环境并检查探查器时,我可以看到我被授予了ROLE_ADMIN角色,但我仍然获得了组的筛选列表。

我已经在我的控制器和Symfony的RoleVoter.php中放入了一些调试代码。我的控制器($this->securityContext->getToken())中的Token和RoleVoter.php中的Token的字符串表示是相同的,但当我使用$token->getRoles()时,我会得到两个不同的数组。

我的用户和角色通过用户和角色实体存储在数据库中。这是我发现的bug还是我做错了什么?

终于拿到了。一分钟前我突然想到了一个模糊的想法。这个问题是由我自己的RoleHierarchyInterface实现引起的。我最初的想法是复制Symfony自己的,但从ORM而不是security.yml加载它。但正因为如此,我不得不完全重写buildRoleMap()函数。差异如下:
 private function buildRoleMap()
 {
     $this->map = array();
     $roles = $this->roleRepo->findAll();
     foreach ($roles as $mainRole) {
         $main = $mainRole->getRole();
 -       $this->map[$main] = array();
 +       $this->map[$main] = array($main);
         foreach ($mainRole->getInheritedRoles() as $childRole) {
             $this->map[$main][] = $childRole->getRole();
             // TODO: This is one-level only. Get as deep as possible.
             // BEWARE OF RECURSIVE NESTING!
             foreach ($childRole->getInheritedRoles() as $grandchildRole) {
                 $this->map[$main][] = $grandchildRole->getRole();
             }
         }
     }
 }

这种情况-角色已设置并显示在Symfony的探查器中,但isGranted返回false-当角色名称不以前缀role_开头时可能发生。

错误的角色名称:USER_TYPE_ADMIN

正确的角色名称:ROLE_USER_TYPE_ADMIN

最新更新