如何为我的 symfony2 网站实现权限角色/组系统

Posted

技术标签:

【中文标题】如何为我的 symfony2 网站实现权限角色/组系统【英文标题】:How to implement a permission roles/groups system for my symfony2 website 【发布时间】:2013-10-03 01:10:35 【问题描述】:

[QUESTION] 对于任何可以参与并提供想法的人来说,这实际上更像是一场头脑风暴。我想首先解释我想要做什么,我的一些想法,并希望能就如何解决这个问题得到一些好的想法。

    [问题] 我想为我的网站实施权限系统。 该站点将有一个用户登录系统,该系统将允许管理员用户 操纵系统中所有其他用户的权限。这 系统将具有查看、编辑、创建等基本权限 并删除,也许还有一些额外的。此外,这些 权限将按用户角色分组。例如, 创建、编辑、删除和查看权限将关联到 系统中的经理角色,但非经理角色只是 与权限“视图”相关联。

    [我一直在调查的内容] 我一直在挖掘的一个想法 into 是使用访问控制列表。我可以创建一个界面 这将允许用户将权限关联到组,然后 将这些组附加到系统中的用户。我不确定 不过,该实现将使用 ACL。

    在 symfony2 框架?

[更新] 如前所述,但我还需要一个允许我为角色动态创建权限并将其分配给用户的系统。此外,我需要一种简单的方法来检查系统中的这些权限,以增强控制器和模板呈现的行为方式。

**如果我的帖子有误或出现在错误的线程中,请提供正确的位置让我发帖

【问题讨论】:

到目前为止我发现的最新解决方案应该是 1) 使用 FOSUserBundle 为用户动态管理组和角色。 2) 创建一个管理界面,我可以在其中使用 symfony2 ACL 将权限 EDIT/DELETE/VIEW/CREATE 分配给角色。在这一点上,我应该能够基于 FQCN 分配权限,或者为了进一步细化 Object 本身或其字段。我可以随时通过容器访问安全上下文,并查看是否为给定用户的任何域对象/类授予访问权限。这应该允许我根据需要拒绝访问或授予访问权限。 你应该看看 Sonata Admin Bundle 我试过了,但演示失败了,文档不清楚它的作用、工作原理和外观。所以我不得不转向另一个方向。 我一直在使用它并且对它非常满意,但是它有一些限制,我应该同意文档很烂!但是代码没有:)当我尝试演示时效果很好,但是安装它可能会很痛苦,我仍然建议尝试一下,因为它可以节省很多时间,但如果你不喜欢它,那么最好运气:) 你知道用户/通行证吗?我通过电子邮件向一直在 github 上为捆绑包做出贡献的开发人员发送了电子邮件,但没有回复。当我尝试使用建议的凭据登录时,它只是说帐户已禁用。 【参考方案1】:

只需使用 FOSUserBundle,它可以让您完全按照自己的意愿行事。

您将为用户和管理员创建角色。

【讨论】:

仅 FOSUserBundle 无法解决我的全部问题。 FOSUserBundle 减轻了创建登录界面的繁重工作,并提供了对角色分组的支持。但是,它没有提供任何方法来管理整个应用程序的安全性。基本上我需要的是,它编写一个界面,可以动态地为角色创建分配权限并将这些角色分配给组。 FOSUserBundle 确实为问题的第一部分提供了一个很好的解决方案。我可以访问用户实体或覆盖它提供的注册新用户表单以合并角色分配。【参考方案2】:

您可以使用 Symfony 轻松实现上面提到的权限系统。 为ROLE_MANAGER、ROLE_USER等用户创建不同的角色,并根据用户角色限制对特定路径的访问。例如,只有当用户具有 ROLE_MANAGER 时,才能访问 /admin/*。

Symfony 的文档详细介绍了所有这些概念。您可以点击here访问文档。

【讨论】:

您提供的当前建议在某种程度上限制了我的需求,这是我在问题中没有正确阐明问题的错。我需要一种动态添加权限的方法。我不能使用 config.yml,因为它静态地为我的路由分配访问控制。在我的系统中,根据为用户设置权限的方式,他们将能够访问任何内容。【参考方案3】:

我已经实现了几个管理员用户角色,管理员可以在其中分配和删除角色。至于动态创建新角色还没有做到这一点。我相信尽管您可以使用提供的角色做所有需要的事情

路线 您可以按照 Praveesh 的建议保护路线。您可以从管理页面分配这些角色,并使用 ROLE_ADMIN 访问的用户循环,然后在您的树枝中进行类似的操作

                     <td>
                        % if 'ROLE_NS' in user.roles %
                            <form action=" path('admin_remove','id':user.id) " method="post" name="overview">
                                <input type="hidden" name="role" value="ROLE_NS" />
                                <button type="submit" class="btn btn-danger btn-xs"  value="demote">demote </button>
                            </form>
                        % else %
                            <form action=" path('admin_add','id':user.id) " method="post" name="overview">
                                <input type="hidden" name="role" value="ROLE_NS" />
                                <button type="submit" class="btn btn-success btn-xs"  value="demote">promote </button>
                            </form>
                        % endif %
                    </td>
                    <td>
                        % if 'ROLE_ADMIN' in user.roles %
                            <form action=" path('admin_remove','id':user.id) " method="post" name="overview">
                                <input type="hidden" name="role" value="ROLE_ADMIN" />
                                <button type="submit" class="btn btn-danger btn-xs"  value="demote">demote </button>
                            </form>
                        % else %
                            <form action=" path('admin_add','id':user.id) " method="post" name="overview">
                                <input type="hidden" name="role" value="ROLE_ADMIN" />
                                <button type="submit" class="btn btn-success btn-xs"  value="demote">promote </button>
                            </form>
                        % endif %
                    </td>

还有一个类似的控制器

 /**
 *@Route("/add/id", name="admin_add")
 *@Method("GET","POST")
 */
public function addAction(Request $request, \AppBundle\Entity\User $user)

   // var_dump($user);
    $role = $request->request->get('role');
    $em = $this->getDoctrine()->getManager();
    $user->addRole($role);
    $em->persist($user);
    $em->flush();

    return $this->redirectToRoute('admin');


/**
 * @Route("/remove/id", name="admin_remove")
 *
 */
public function removeAction(Request $request, \AppBundle\Entity\User $user)

    $role = $request->request->get('role');
    $em = $this->getDoctrine()->getManager();
    $user->removeRole($role);
    $em->persist($user);
    $em->flush();

    return $this->redirectToRoute('admin');

至于他们是否可以创建更新视图删除,我会使用 ACL 看看我的问题

ACLs protecting a entities entity

在我看来,使用 ACL 只是意味着你需要在每条路由上做更多的检查

$authorizationChecker = $this->get('security.authorization_checker');
  if(false == $authorizationChecker->isGranted('VIEW',$organisation) )
    throw new AccessDeniedException();
  

【讨论】:

以上是关于如何为我的 symfony2 网站实现权限角色/组系统的主要内容,如果未能解决你的问题,请参考以下文章

Mongo - 如何找出我连接的用户的角色?如何为用户分配完全读写访问权限?

Symfony2 - 显示动态可选角色

如何为 Symfony2 站点正确设置 Varnish?

如何为我的网站数据库中的 mysql 数据库表授予超级权限

如何为我的场景实现单点登录?

如何为SQL Server2008添加登录账户并配置权限