4

有没有人有在 MongoDB 中建模访问控制的示例?我想到的情况是:

有一组资源,每一个都是它们自己的文档(例如汽车、人、树等)。

用户可以通过显式授权或通过成为资源的所有者、存在于另一个集合(例如角色)或其他一些隐式方式来隐式地访问资源。

在一个可以应用跳过和限制选项(用于分页)的 collection.find() 方法中,有没有办法检查所有这些显式和隐式路径并产生用户可以访问的资源的结果?

在 MySQL 中,我们使用带有资源 ID、授予用户 ID、授权用户 ID 和操作(读取、写入等)的授权表对此进行了建模。然后,在一个查询中,选择至少一个子查询为真的所有资源,然后子查询检查所有不同的访问路径,例如一个检查授权,一个检查所有权等。

我只是无法在 MongoDB 中这样做,我不确定它是否可能......

谢谢

4

2 回答 2

3

您一次不能查询多个文档。理想情况下,访问控制不应该成为业务逻辑的一部分。您的后端 php/c#/language 应该确保当前请求已获得授权。如果是这样,那么只需查询请求的文档。

如果您觉得,您需要在 mongodb 中实现完全相同的结构,我建议您不要这样做,那么您将需要嵌入所有这些字段(来自其他 mysql 表的字段,可帮助您识别请求是否被授权)在每个集合的每个文档中。您将复制数据(对其进行非规范化)。这带来了确保所有副本都已更新并具有相同值的问题。

编辑1:

让我们谈谈汽车文件。要跟踪其所有者,您将拥有owner财产(这将包含_id所有者文件)。要跟踪所有可以“使用”(显式授予)汽车的用户,您将拥有一个数组allowerdDrivers(这将包含_id每个user文档的 )。让我们假设发出请求的当前用户属于“管理员”角色。该user文档将具有一个数组applicableRoles,用于存储_id每个适用的角色文档。

要检索用户有权访问的所有汽车,您只需进行两次查询。一个来取他的角色。如果他是管理员,则归还所有汽车。如果他不是,则进行另一个查询,其中owner等于他的 idor allowedDrivers包含他的 id。

我了解您的实际用例可能更复杂,但有可能有一种面向文档的方法来解决这个问题。您必须意识到,数据在文档中建模的方式与在 RDbMS 中建模的方式大不相同。

于 2012-11-25T08:25:42.720 回答
0

在业务逻辑中这样做会非常缓慢且效率低下。

怎么会这样?这是业务逻辑,如果用户 a 拥有帖子 b,则让他们执行操作(MVC 样式),否则不要。

这对我来说听起来像是业务逻辑,大多数框架都认为这个业务逻辑被放置在控制器动作中(MVC 范式);即在 PHP Yii 中:

Yii::app()->roles->hasAccess('some_view_action_for_a_post', $post)

我认为通过在数据库端执行此操作,您将存储层与业务层混淆了。

此外,由于某些基于角色的权限操作可以让您提交的查询非常复杂,因此必须有很多子选择。考虑到 MySQL 如何创建和处理结果集(子选择不是 JOINS),我感觉这些查询的扩展性不是特别好。

此外,您还必须考虑何时要更改角色或定义角色的函数,它可以访问某个对象,您必须直接更改 SQL 查询,而不仅仅是将角色添加到角色表并分配对象该角色的属性并分配该角色的用户(AKA 代码更改)。

因此,我会认真研究其他语言(以及您自己的)的其他框架如何执行 RBAC,因为我认为您已经模糊了界限,并且您所做的事情让您的生活变得非常艰难,实际上这里可能是一个很好的起点: node.js 和 express.js 中基于组/规则的授权方法

于 2012-11-25T16:23:25.353 回答