5

一般说明

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

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

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

在决定是否允许用户做某事时,权限继承如下:

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

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

  • 允许用户...
  • 编辑拥有用户的所有权限+ ...
  • 版主拥有编辑的所有权限+ ... - ...
  • Admins 拥有 Editors + Moderators的所有权限

注意:我应该能够从数据库中请求当前用户可以编辑/查看的最后 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”可以编辑“类别 1”及其所有嵌套类别中的所有项目。
  • 编辑者可以编辑除所有者标记为超级管理员的项目之外的所有项目。

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

执行

我搜索了 symfony 文档、stackoverflow 等。有很多关于安全和 acls 主题的有趣文章和问题,但我找不到处理这样一个系统的最佳方法。

很明显,我需要某种类型的动态查询构建器来根据定义的规则根据存储在数据库中的信息过滤行。我假设第二步(涉及未存储在数据库中的信息,如当前服务器负载)可能是实现一个投票者(参见本文这个问题中的投票者示例),或者有时甚至更简单的解决方案(例如规则取决于请求的路径)。如果解决方案涉及多件事情来处理权限,还请描述如何将它们集成在一起使用。

问题

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

4

1 回答 1

1

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

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

使用安全投票器,您可以实现任何您可以想象的访问控制逻辑。

选民的工作就像

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

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

您可以为单个操作实现多个投票者,并定义策略 hove 来决定结果投票。

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

您还可以定义自定义角色层次结构以简化安全工作

另请阅读SecurityComponent上的这些文档

于 2015-02-20T09:31:12.553 回答