我是使用 PHP 和 MySQL 创建 Web 应用程序的团队的一员。 该应用程序将有多个具有不同角色的用户。 该应用程序还将以地理分布的方式使用。 因此,我们需要创建一个在以下两个级别运行的访问控制系统:
- 控制特定 php 页面的用户权限,即根据用户的角色提供或拒绝对特定页面(或用户界面元素)的访问。 例如:用户可能被允许访问“学生”页面,但不允许访问“教师”页面。
- 控制特定数据库记录的用户权限,即修改数据库查询以便仅显示特定记录。 例如,对于城市级别的用户,仅应显示与用户的特定城市相关的那些记录,而对于国家级别的用户,应显示该国家/地区所有城市的记录。
我需要帮助设计一个可以处理这两种类型的访问控制的系统。 点号。 1 看起来很简单。 然而,我完全不知道如何在不硬编码 SQL 查询中的信息的情况下执行第 2 点。
任何帮助,将不胜感激。
预先感
谢维纳亚克
I am part of a team creating a web application using PHP and MySQL. The application will have multiple users with different roles. The application will also be used in a geographically distributed manner. Accordingly we need to create an access control system that operates at the following two levels:
- Controls user permissions for specific php pages i.e. provides or denies access to specific pages (or user interface elements) based on the user's role. For example: a user may be allowed access to the "Students" page but not to the "Teachers" page.
- Controls user permissions for specific database records i.e. modifies database queries so that only specific records are displayed. For example, for a user at the city level, only those records should be displayed that relate to the user's particular city, while for a user at the national level, records for ALL CITIES in the country should be displayed.
I need help on designing a system that can handle both these types of access control. Point no. 1 seems to be simple enough. However, I am completely at a loss on how to do point number 2 without hardcoding the information in the SQL queries.
Any help would be appreciated.
Thanks in advance
Vinayak
发布评论
评论(5)
几个月前我也遇到过类似的情况。 我发现,如果您只检查单个项目(或数量相当少的项目)的访问级别,像 Zend_ACL 这样的工具就可以很好地工作。 当您需要获取允许用户访问的大量项目列表时,它会失败。 我使用 业务代表 模式精心设计了此问题的自定义解决方案。 BD 提供可应用于特定上下文的业务逻辑。 本场景下发了一条SQL逻辑,作为子查询的过滤条件。 请参见下图:
(来源:epsi.pl)
和顺序说明调用顺序的图表:
(来源:epsi.pl)
不幸的是,我在博客中介绍了此解决方案全部都是波兰语,但您可能会发现方便的代码和图表。 我可以说,实现并不是小菜一碟,但在性能方面,与列表中每个元素的迭代访问检查相比,它是冠军。 此外,上述基础设施不仅处理列表中的一种类型的项目。 它可以在访问不同的列表时提供服务,无论是城市列表、国家列表、产品列表还是文档列表,只要列表上的项目实现了 IAuthorized 接口。
I was in similar situation few months ago. I found that tools like Zend_ACL work great if you just check access level to single item (or reasonably low number of them). It fails when you need to get a huge list of items the user is allowed to access. I crafted custom solution to this problem using Business Delegate pattern. BD provides business logic that can be applied in specific context. In this scenario a SQL logic was delivered and used as filtering condition in subselect. See the following diagrams:
(source: epsi.pl)
And sequence diagram that illustrates calls order:
(source: epsi.pl)
I blogged about this solution, unfortunately it's all in Polish, but you may find pieces of code and diagrams handy. What I can say, the implementation is not a piece of cake, but performance-wise it's a champion when compared to iterative access checking for each element on the list. Moreover, the infrastructure above handles not only one type of items on the list. It can serve when accessing different lists, be it list of cities, countries, products, or documents as long as items on the list implement
IAuthorizable
interface.不知道你的问题的细节,但 Zend Framework 有一个相当有效的 ACL 和 AUTH 您可能想要的组件集看着。 好东西,比如非常精确的访问控制、持久性存储数据、高级条件规则。
Don't know about the details of your problem but the Zend Framework has a rather potent ACL and AUTH set of components you may want to look at. Good stuff like very precise access control, storing data for persistance, advanced conditional rules.
在我看来,您需要的是这样的:(我将使用国家/州/城市示例)
对于城市用户,显然只搜索并显示与其 ID 匹配的城市相关记录。 不过,对于州或国家级别,请搜索与每个城市相关的所有记录,这些记录的 ID 与该国家(或州或您拥有的国家)匹配。
所以基本上,每个子组都依赖于它上面的组,尽管我记错了,但我相信您可以使用子查询来实现这一点。
It seems to me like what you need is this: (I'll use a country/state/city example)
For a city user, obviously search for and display only those records pertaining to the city that matches their ID. For a state or national level though, search for all records pertaining to each city that has an ID matching that nation (or state or what have you).
So basically, each sub group is dependant on the group above it, and although I don't recall correctly, I believe you can use sub queries to do the trick from there.
我有类似的解决方案要构建,到目前为止,我决定使用规范和角色,因此实际上一个角色将附加一些权限规范。 如果它们都满足,则授予权限,否则 - 它将回退到资源默认访问权限。
我正在寻找已经实施该解决方案的人,但似乎没有人这样做。 希望它不会失败:)
I have similar solution to build and so far I've decided to use specifications and roles, so in fact one role would have some privilege specifications attached. If they all are satisfied, the permission is granted, otherwise - it falls back to the resource default access.
I was looking over to find someone already implementing the solution, but it seems no one did. Let's hope it won't be a fail :)
如果您不知道如何执行此操作,我会使用 PHP 框架,例如 Zend Framework、CakePHP 或 Symfony。 他们已经为您完成了繁重的工作,并且已经制定了某种类型的访问控制方案。
If you don't know how to do this I would use a php framework like Zend Framework, CakePHP, or Symfony. They have done the heavy lifting for you and have some type of access control scheme already in place.