实施ACL约束,不仅仅允许/拒绝

| 我已经开发了一个小型但有效的MVC样式框架,供在应用程序中使用,并且正在实现ACL每个请求检查。 快速详细信息:PHP 5.3+; MySQL 5.1+;自定义框架,“类似于MVC” 到目前为止,ACL检查很简单,“拒绝-如果不是白名单”;可以将每个“ 0”分配给某些请求处理程序的权限。例如:
privilege                       permission
+----------+---------------+    +---------------+---------------+
| group_id | permission_id |    | permission_id | handler_key   |
+----------+---------------+    +---------------+---------------+
|     1    |       1       |    |       1       | lorem_ipsum   |
|     1    |       2       |    |       2       | hello_world   |
|     2    |       3       |    |       3       | foobar        |
+----------+---------------+    +---------------+---------------+
(为简洁起见,不包括
user
group
,但是它们的模型并不稀奇) 无论如何,我的框架都通过处理程序/路径表将URI路由到适当的ѭ4(以解耦文件系统体系结构),然后将给定与请求关联的ѭ5列入白名单,然后将请求分派到处理程序。 我很好奇,实现存储/检查任意(用户定义)约束的最佳方法是什么?案例示例为: 仅允许给定的组在工作日的8:00至17:00之间调用处理程序。 只允许给定的组调用处理程序来修改“拥有的”数据;即:由相关的“ 2”创建的数据。此检查可能涉及对与要由处理程序修改的内容相关联的
user_id
字段以及与请求相关联的
user_id
字段的检查。 我有一个“ 10”列,但是随着更多功能,组和约束要求的引入,它并不是面向未来的。我在朝以下方向思考,但是该怎么用呢?
permission
+---------------+----------------------------+
| permission_id | handler_key   | constraint |
+---------------+---------------+------------+
|       1       | lorem_ipsum   |     ?      |
|       2       | hello_world   |     ?      |
|       3       | foobar        |     ?      |
+---------------+---------------+------------+
不必要的澄清: (注意:代码是在此处键入的,而不是项目中的copypasta) 在这里澄清一些行话;对于熟悉MVC原型的人,处理程序(特别是Web处理程序)本质上是控制器。 它们的特定实现是单个PHP文件,该文件返回要由调度程序或子处理程序调用程序调用的函数。例如:
<?php
    $meta = array(\'subhandlers\' => array());
    return function($request, $response) use($meta){
        $response[\'foo\'] = \'bar\';
    };
我的框架使用Web处理程序和API处理程序。 Web处理程序将数据馈入到生成HTML的响应对象(基本上是分层视图的集合)中。数据是通过调用API处理程序获得的,这些处理程序仅返回原始数据(API处理程序可以视为模型的表示形式,可以回到典型的MVC)。 复合处理程序本质上是一个抽象层,因为它们本身是处理程序,它们调用处理程序以聚合数据。我当前的ACL检查实现对所有嵌套处理程序进行粗略检查(通过
$meta
,这是一个声明为充当处理程序元数据标头的数组变量),例如:
<?php
    $meta = array(\'subhandlers\' => array(\'my_subhandler\'));
    return function($request, $response) use($meta){
        $someData = Caller::call(\'my_subhandler\', array($request, $response));
        $response->bind($someData);
    };
    
已邀请:
我在评论中发布的视频与您分享的视频具有相似的想法,但是没有代码。 关于您的问题,我从未实现过,并且我只有一个模糊的想法,即如何(或无法)构建这样的系统,因此请使用(或几个)盐粒作为输入。 您要做的第一件事是确定用户可以限制的约束,忘记任意数据,定义用户可以定义和不能定义的内容是这里最重要的一点。 下一步是定义可以轻松解析和验证的某种符号或数据结构,例如,在基于时间的限制中,您可能具有以下可能性: 具体日期时间(2011-05-26) datetime范围(2011-05-26至2011-05-31) 递归日期时间(201x-05-26或每个星期五) 逻辑(和/或/异或)运算符 如果您有适当的表示法,则可以通过标记化规则并可以使用DatePeriod或DateInterval或甚至像crontab这样的模运算符来轻松解析和验证。 您的第二个示例:   只允许给定的组调用   处理程序,以修改“拥有的”数据;即:   关联用户创建的数据。 对我来说听起来像普通的ACL: 资源:特定数据 角色:特定用户 然后,当然,您拥有更复杂的规则,例如:   批准记录的用户必须   具有相同或更高的水平(在   与用户相同的安全名称空间)   谁创建了记录,但他们不能   成为同一用户。 我认为这种规则必须特定于应用程序逻辑,并且要实现真正的通用解决方案将极其困难,Zed Shaw在演讲中提到,他想出了一个仅使用400行代码的完整解决方案,对学习他的工作方式非常感兴趣。 标志(以位存储)是一种指定(一个或多个)约束的组合的好方法(尽管很隐秘),但以我的经验,最好先定义所有约束。 由于您似乎不太清楚要检查的约束,因此建议您为要检查的几种限制类型创建符号: 基于时间 基于用户/资源 ... 然后实施解析的方法(可能使用表示版本的符号,以便将来进行迁移)并验证所有约束。 很抱歉,如果我的回答没有太大帮助,但是我发现这个问题非常有趣,希望其他人提出更好的建议,AFAIK并没有魔杖可以解决这个问题。     
在回顾了我的架构选择之后,对我来说很明显,我可以利用我的
handler
样式请求处理方法。 (请以批判和/或嘲笑和/或高五级作为主张) 为此,可以将检查用户是否具有权限的请求仅视为另一个请求,因此需要它自己的处理程序。例如:
permission
+---------------+--------------------------------------+- - - - - -+
| permission_id | handler_key | constraint_handler_key | arguments :
+---------------+-------------+------------------------+ - - - - - +
|       1       | lorem_ipsum | user_check_owner       |           :
|       2       | hello_world | user_check_owner       |           :
|       3       | foobar      | time_check             |           :
+---------------+-------------+------------------------+ - - - - - +
通过添加一个
NULL
-able
constraint_handler_key
列,可以以编程方式创建新约束并进行管理委派。 当请求触发时,框架将聚合处理程序链,并将其与白名单进行比较,就像已经做的那样。如果存在“ 18”(可能带有上表所示的参数),它将在与该请求类型相关联的“ 20”中进行查找:
// web handlers handlerTable example
return array(
    \'lorem_ipsum\' => PATH_WEB_HANDLERS . \'path/to/lorem_ipsum.handler.php\',
);

// acl handlers handlerTable, follows same format
return array(
    \'time_check\' => PATH_ACL_HANDLERS . \'time/check.handler.php\',
);
(API处理程序也相同) 预期ACL处理程序仅返回布尔值,从而继续或结束权限检查序列,从而整个或整个请求。
// time_check acl handler, allow if current time between 9am - 5pm
return function($request){
    $dayBegin = time() - (time() % 86400);
    return (time() > ($dayBegin + 32400) && ($dayBegin + 61200) > time());
};
遗漏18英镑的情况作为基本白名单检查处理;允许/否。 因此,我的应用程序目录将开始如下所示:
:
+- application/
|   +- config/
|   +- views/
|   +- handlers/
|       +- acl/
|       +- api/
|       +- web/
:
    

要回复问题请先登录注册