如何使用Symfony 2创建如下的权限系统?

时间:2012-04-24 23:04:15

标签: security permissions symfony implementation acl

一般说明

系统应处理组织成嵌套类别的大量项目(请参阅下面的可视示例),同时让客户端能够定义权限规则(请参阅下面的权限规则)。它还应该处理独立于任何项目的不同一般权限(例如“可以查看特定页面?”或“可以邀请新成员?”)。

所有用户都被组织成小组。每个用户都有一个他所属的主要组,但他也可能有一些额外的辅助组。

可以将一些用户配置为超级管理员,并且应该允许他们做任何事情。

在决定是否允许用户执行某些操作时,权限继承如下:

  • 从主要群组权限开始
  • 允许任何用户的其他群组允许的所有权限
  • 如果已定义,请检查用户特定的权限(允许或拒绝,与上述内容无关)。不必定义用户特定权限,如果未定义用户,则只需从组权限继承权限

定义组权限时,客户端可以使用继承来表示:

  • 允许用户...
  • 编辑拥有用户 + ...
  • 的所有权限
  • 版主拥有编辑的所有权限 + ... - ......
  • 管理员拥有编辑 + 版主
  • 的所有权限

注意:我应该可以从数据库中请求当前用户可以编辑/查看的最后10个项目,每个项目的权限应该由数据库决定,我不是如果我可以根据存储在数据库中的信息来决定,那么我想过滤应用程序级别的权限。

权限规则

规则可能取决于项目的任何属性(例如项目所有者的主要组,创建时间,类别等......),该信息存储在数据库中。

规则还可以取决于当前用户的任何属性(例如,注册日期,邀请的成员),请求的操作(例如,查看,列表,重命名,撤消删除等)以及运行时已经可用的其他信息(例如url参数,配额限制,项目内容,服务器负载),该信息可用于php脚本。

请参阅以下示例规则。

数据库架构的可视化示例

Category 1
   Nested Category A
      item x
   Nested Category B
      Deeply Nested Category
         item w
      item y
Category 2
   item z

目前,数据库架构如下所示,但如果需要,我可以更改它: (当然这只是模式的一部分,还有其他表和字段)

id | title  | owner_id | category_id
====================================
1  | item x | 2        | 3
2  | item y | 1        | 4
3  | item z | 3        | 2
4  | item w | 1        | 5

类别

id | parents | title
=====================================
1  | null    | Category 1
2  | null    | Category 2
3  | 1       | Nested Category A
4  | 1       | Nested Category B
5  | 1/4     | Deeply Nested Category

用户

id | name | group | all_groups | is_super_admin
===============================================
1  | Tony | 5     | 5          | 1
2  | John | 5     | 5,8,6      | 0
3  | Mike | 4     | 4,7        | 0
4  | Ryan | 6     | 6          | 0

示例规则

以下规则只是应该实施的真实案例的样本。

  • 用户可以在提交()
  • 后的5分钟内编辑自己的项目
  • 用户'John'可以编辑'Category 1'及其所有嵌套类别中的所有项目。
  • 编辑者可以编辑除其所有者被标记为超级管理员的项目以外的所有项目。

请注意,这些规则可以在数据库级别决定,就像我的大多数规则一样。

实施

我搜索过symfony docs,stackoverflow等。关于安全性和acls的主题有很多有趣的文章和问题,但我找不到处理这种系统的最佳方法。

很明显,我需要某种类型的动态查询构建器来根据定义的规则根据存储在数据库中的信息来过滤行。我假设第二步(涉及未存储在数据库中的信息,如当前服务器负载)可能是为了实现选民(参见this articlethis question中的选民示例),或者有时甚至更简单的解决方案(例如依赖于所请求路径的规则)。如果解决方案涉及多个事项来处理权限,请同时描述如何集成和使用它们。

问题

我正在问如何实现这样一个系统,请不要回答指向symfony文档或其他资源的链接,其中包含一般的想法和常见的简单案例。请在回答之前阅读并理解我的案例。

1 个答案:

答案 0 :(得分:1)

我意识到这个问题很老,但是答案适用于Symfony 2.3+,所以我在这里发布。

对于这种方法,您应该使用SecurityVoters之类的内容。

对于安全选民,您可以实现访问控制的任何逻辑,您可以想象。

选民像

一样
$this->get('security.authorization_checker')->isGranted('update',$post);

将检查所有选民,谁可以操作邮政实体(参见文档)并将他们的投票与选择策略(肯定,共识,一致)结合起来,以决定当前用户是否有权更新帖子(对于您的第一个例子) )

您可以为单一行动实施多名选民,并定义策略以决定最终投票。

您可以存储在存储库中的所有组和权限,并使用选民内部的学说获取它们。

您还可以定义自定义角色hierarhy以简化安全性工作

另请阅读SecurityComponent

上的这些文档