2012-03-11 60 views
12

我想听听关于优化我们的模式以实现以下内容的最佳方法的一些想法。使用Symfony2管理用户/组对象权限的最佳方法

我们有许多的对象/ DB条目(事件,地点等),其中有一些子对象(指相同的权限应用 - 图像,METAS等)

用户可以属于组,以便家长诸如事件,场地之类的对象可以由所有人进行编辑/查看,仅限于一个用户组。

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

每个父对象,如场地作为user_id和group_id的列。

工作正常(在symfony 1.4中),但它很混乱 - 每个查询任何事情都必须做复杂的连接才能获得可能的组等等......我们希望找到一个更简单的方法。

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

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

所以...我很想听听有关如何做到这一点的想法 - 我们也愿意将symfony留给一些具有可扩展ACL解决方案但尚未发现任何内容的东西(php或ruby)尽管我们希望继续使用Sf,但对此也是开放的。请注意,我们打算在重要的情况下使用MongoDB。

回答

11

根据我的理解,ACL用于在特定场景下为特定人员提供特定对象的访问权限。你所描述的是更通用的,但它只是偏离了Symfony2的安全概要(此人具有“管理员”角色,但仅限于包含在特定组中的对象)。

ACL不应该用来存储一堆东西,因为如果它太大,检查它可能会变得很贵。因此,当添加新用户时,甚至在新组中添加新对象时,默认情况下会在这里抛出一堆东西(如果使用ACL,则必须在创建组时向组中的每个人添加条目新的对象),会经过一段时间对性能进行征税......

我目前正在研究使用Symfony2中的Web应用程序的可能性,但我打这个安全的东西墙也一样,我们有类似的需求。我在Symfony2中没有专家,但是从我在已经看了,你可能有几种选择:

  1. 创建一个选民处理这个问题。选民允许您检查授权令牌,并根据处理方式返回是否授予访问权限或拒绝访问权限。因此,您可以创建一个自定义选举器来检查用户的组,并尝试将其与该对象所在的组进行匹配。如果是,则返回ACCESS_GRANTED,否则返回ACCESS_DENIED或ACCESS_ABSTAIN,如果选举器对当前检查无效。编辑:这是一个链接到选民的Symfony2食谱:

  2. 也可能想研究SecurityContext接口。这提供了处理确定对象访问的“isGranted()”方法。如果选民不够简单,你可能不得不去创建一个新的SecurityContext类的路线;我认为这会多一点参与。

就像我说的,我不是亲,也没有解决办法;这些只是我正在研究尝试解决的一些方向(我的感受是)类似的问题。希望这有些帮助。

1

自从我发布我的原始答案到现在已经有一段时间了,但是想要跟进另一个解决方案,我们目前正在使用这个解决方案。

尽管Symfony提供了一个安全/ ACL层使用,但您不需要使用来使用它,或者至少完全使用它。

在几乎任何在你的代码的时间点,你可以抛出一个Symfony\Component\Security\Core\Exception\AccessDeniedException和安全层会“踢”,并为您处理它,喜欢将用户重定向到登录页面等

一些这种交互可能需要一些更高级的防火墙设置才能完全按照你想要的方式工作。简而言之,虽然Symfony提供了一些很棒的机制和功能来帮助构建ACL,但您不必为使数据和流程适合他们定义的内容而努力。

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