可扩展的基于规则的访问模式


Extensible rule-based access pattern

我用一些PHP逻辑控制对一些静态web资源的访问。因为通过Web服务器进行基于目录的授权是不合适的,也不容易实现。

这些因素的组合决定了访问是被授予还是被拒绝。这些规则会不时地改变。

一开始,它是一个简单的regex路径匹配,并检查一个会话变量。现在更复杂了,因为涉及到更多的变量。

我想知道如何进行重构,这样就可以快速轻松地更改规则。当它是一个简单的"if this AND this,then delivery,else 403"时,用直接的PHP做它是很好的。现在情况更为复杂,有几个级别的嵌套,每个级别都有共同但略有不同的条件。这一切都很容易重构,但它并不是最直观、最容易更新的。

我在想两件事中的一件。

  1. 为每个顶级条件建立类,并使用策略工厂来选择正确的授权。从一个包含公共位的基类派生它们,并重载任何必要的内容。我认为,当一些情况发生变化时,这仍然可能会出现一些混乱。

  2. 制作一个简单的引擎,迭代一个有序规则的2d数组,有点像防火墙规则。类似于:<allow|deny>, <auth_group>, <path_regex>, <other vars>

我还没有完全考虑过这一点,但它似乎更容易更新,也更容易作为一个人阅读。

你会怎么做?有没有一个既定的模式或库我可以用来做这件事?

不久前,我在另一个应用程序中遇到了类似的问题。我想要一种简单更新的方式,根据几个级别的条件将规则和结果链接在一起。这并不像那个应用程序那么复杂,但我很想听听人们用来解决这类问题的模式。

您可能想要查看Zend_Acl,它是一个面向对象的PHP类,用于管理资源层次结构上的特权层次结构。您可能无法按原样使用此组件,但它可以让您深入了解如何实现自己的系统。

Zend_Acl是Zend Framework PHP 5类库的一部分,但与ZF中的许多类一样,Zend_Acl可以独立使用。没有必要使用Zend框架的其余部分。

您还可以使用一个小型逻辑引擎(想想prolog)来轻松地陈述事实和规则,这将允许您快速查询是否应该允许访问资源。像这样基于逻辑的规则引擎通常非常高效,应该可以让你非常容易地为这类问题领域建模解决方案。

我会使用规范模式。它允许您组合规则。您甚至可以创建一个类来表示将在IsSatisfiedBy()方法中运行(遵循模式)的复合规则。