如何编写和存储动态权限约束?

时间:2011-09-23 09:24:50

标签: php mysql web-applications authorization acl

我以前经历过这个问题,但还没有找到一个简洁的解决方案。

假设我们有一个应用程序,客户可以使用该网站预订课程,管理员也可以预订有关客户的课程。代表使用后端系统。我试图建立一种方法让HR管理员编纂应用于can_make_booking等权限的约束,因为权限不仅仅是布尔值,不应该硬编码到应用程序中

目前,只要课程日期至少是“ ”,客户就可以预订。在将来的日期标准通知中,他们预订的不超过可用的地点数量,并且他们至少支付到期金额(如果他们的帐户设置为发票,则为零)。管理人员可以使用后端应用程序进行预订,只要预约日期是在此之后的任何时间。

我想象这样的事情。让HR管理员添加如下所示的权限限制:

role      permission    constraint
--------  ------------  ----------
customer  make_booking  1
customer  make_booking  2
customer  make_booking  3
manager   make_booking  5

然后是约束表,

constraint  property        operator  value                       OR_parent
----------  ------------    --------  --------------------------  ---------
1           $course_date    >=        strtotime("+$notice days")  NULL
2           $places_booked  <=        $places_available           NULL
3           $paid           >=        $total                      NULL
4           $send_invoice   ==        TRUE                        3
5           $course_date    >=        strtotime("now")            NULL

为客户角色链接这些约束将构建类似于以下eval ed代码(约束#4与作为OR序列的一部分的#3配对):

if($course_date >= strtotime("+$notice days") && $places_booked <= $places_available && ($paid >= $total || $send_invoice == TRUE)){
    // make the booking
}

每个规则都可以在每个阶段独立使用,例如JavaScript和表单验证,以便在出于某种原因无法进行预订时提供反馈。

但是,人力资源部门希望更改客户规则,以便他们一次只能预订3个地方,而$paid金额必须至少为$deposit金额?理想情况下,我想让他们动态地构建这些php规则,而不让他们访问硬编码。可以对属性和值进行清理,以使eval代码不成问题。我不想对每个规则的每个组合进行硬编码,因为在某些情况下,没有明确的方法可以提前猜出人力资源管理员的逻辑。

我查看了assertions的Zend_ACL版本,但它们似乎并没有提供我正在寻找的动力。实现这些动态约束的好方法是什么?来自其他环境的任何想法?谢谢!


Zed Shaw在CUSEC演讲中谈到了为什么&#34; ACL已经死亡&#34; - http://vimeo.com/2723800

1 个答案:

答案 0 :(得分:1)

嗯,这是仍然引发大量讨论的领域之一。有人说[谁? - 认为它是Atwood和其他人一样,但链接逃脱了我,一个可以做任何事情的应用程序已经完成;它被称为C.你想要做的事情几乎就是“过于概括”的区域,尽管我可以看到每次业务规则发生变化时都不需要程序员的价值。

如果我必须实施这样的系统,我想我会尝试将其分解为域。你已经用第二张表做了相对好的工作。只需将其标准化为用于复合业务规则的单独域。您创建一个业务规则,该规则由一个或多个OR-ed组成。每个约束都需要一个受运算符限制的属性。术语可能很棘手,因为它们可以是从属性到函数到复合函数的任何东西。检查业务规则以查看所需内容可能最简单。例如,从属性,布尔值和普通的事情开始,比如'NOW'。

因此,架构本身将由rules组成,其中包含多个constraints(显而易见的好处是,您可以将这些绑定到任何[用户组/商品/时间跨度/其他]域名]你想要的)。反过来,它们由properties组成,可与operators中的一个进行比较(参考表主要是因为您可以为非程序员输入自定义描述性名称,但您可以选择输入自定义在某些时候在其中起作用),当然还有terms之一。最后一部分是最复杂的部分,因此您可能必须使用term_types中的ID对其进行限定,以便您知道自己是在与另一个属性或函数进行比较。您也可以VARCHAR使用PHP创建字段,这应该不会太困难,因为您拥有properties和/或functions中的所有选项。

这是一个非常开放的系统(并且可能有更好的方法),所以除非你知道在业务规则中需要高度的活力,否则它可能不值得做。