【问题标题】:Best way to manage user/group object permissions with Symfony2使用 Symfony2 管理用户/组对象权限的最佳方法
【发布时间】:2012-03-28 00:10:58
【问题描述】:

我想听听一些关于优化架构以实现以下目标的最佳方式的想法。

我们有许多对象/数据库条目(事件、场地等),其中一些具有子对象(意味着应用相同的权限 - 图像、元数据等)

用户可以属于组,因此活动、场地等父对象可以对所有人进行编辑/查看,仅限组,只有一个用户。

目前我们有一个用户、用户组和组表来管理用户和组。

每个父对象(例如场所)作为 user_id 和 group_id 的列。

工作正常(在 symfony 1.4 中)但它很混乱 - 每个查询都必须进行复杂的连接以获取可能的组等......我们希望找到一种更简单的方法。

我对 Sf2 ACL 组件感到非常兴奋,但我被反复告知我不应该使用它来查找用户可以管理的对象 - 而我应该使用 ACL 来确定是否允许用户管理他自己的对象(看起来不是很有用,但无论如何)。

我发现这样做的所有在线替代尝试都是从数据库中提取所有对象然后按 ACL 过滤 - 这对于妈妈和流行网站来说很可爱 - 不会发生一百万个对象。

所以...我很想听听我们如何做到这一点的想法——我们也愿意离开 symfony 去寻找具有可扩展 ACL 解决方案但到目前为止还没有找到任何东西(php 或 ruby​​)的东西如此开放尽管我们很乐意继续使用 Sf。请注意,我们打算在重要的情况下使用 MongoDB。

【问题讨论】:

    标签: symfony acl


    【解决方案1】:

    据我了解,ACL 用于在特殊情况下将特定对象的访问权限授予特定人员。您所描述的更为通用,但它只是偏离了 Symfony2 对安全性的概述(此人具有“管理员”角色,但仅适用于特定组中包含的对象)。

    ACL 不应该用于存储一堆东西,因为如果它变得太大,检查它会变得很昂贵。因此,当添加新用户时,甚至在组下添加新对象时(如果使用 ACL,您必须在创建组时为组中的每个人添加一个条目)新对象),一段时间后将对性能征税......

    我目前正在研究将 Symfony2 用于 Web 应用程序的可能性,但我也遇到了这种安全问题,因为我们有类似的需求。我不是 Symfony2 方面的专家,但根据我的研究,您可能有几个选择:

    1. 创建一个 Voter 来处理这个问题。选民允许您检查授权令牌并根据您的处理方式返回是否授予或拒绝访问权限。因此,您可以创建一个自定义 Voter 来检查用户的组并尝试将其与对象所在的组匹配。如果是,则返回 ACCESS_GRANTED,否则返回 ACCESS_DENIED,如果投票者对当前检查无效,则返回 ACCESS_ABSTAIN。编辑:这是 Symfony2 选民手册的链接:http://symfony.com/doc/current/cookbook/security/voters.html

    2. 可能还想研究 SecurityContext 接口。这提供了处理确定对对象的访问的“isGranted()”方法。如果 Voters 还不够简单,您可能不得不创建一个新的 SecurityContext 类;不过我认为这会涉及更多。

    就像我说的,我不是专业人士,也没有解决方案;这些只是我正在研究的一些方向,试图解决(我的感觉)一个类似的问题。希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      自从我发布我的原始答案以来已经有一段时间了,但想跟进另一种解决方案,我们目前正在使用的解决方案。

      虽然 Symfony 提供了一个安全/ACL 层可供使用,但您没有使用它,或者至少没有完全使用它。

      几乎在您的代码中的任何时间点,您都可以抛出Symfony\Component\Security\Core\Exception\AccessDeniedException,安全层将“启动”并为您处理它,例如将用户重定向到登录页面等。

      其中一些交互可能需要更高级的防火墙设置才能完全按照您的意愿工作。

      长话短说,虽然 Symfony 提供了一些强大的机制和特性来帮助构建 ACL,但您不必努力将您的数据和流程适应他们定义的内容。

      以我们的系统为例,我们的系统中有帐户、角色和组(以及权限)。我们还将数据部分划分为部门。虽然用户可以拥有全局级别的角色和权限,但他们也可以拥有特定于部门的访问权限。这种设置使用内置的 Symfony ACL 功能和访问检查工具几乎无法使用(并不意味着他们的工具没用,事实上它们很棒,它们只是不适合我们的用例)。因此,我们构建了自己的服务(利用一些经过微调的查询),我们在其中传递与检查有关的相关数据,并在检查失败时抛出适当的Symfony\Component\Security\Core\Exception\AccessDeniedException

      【讨论】:

        猜你喜欢
        • 2016-07-09
        • 1970-01-01
        • 1970-01-01
        • 2014-12-15
        • 2019-06-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-10
        相关资源
        最近更新 更多