Permissions 复杂应用程序(RDBMS、图形数据库?)的性能ACL模式
我正在用Java/Spring和至少两个不同的数据库构建一个相当复杂的web应用程序:Permissions 复杂应用程序(RDBMS、图形数据库?)的性能ACL模式,permissions,neo4j,authorization,acl,rdbms,Permissions,Neo4j,Authorization,Acl,Rdbms,我正在用Java/Spring和至少两个不同的数据库构建一个相当复杂的web应用程序: 主要数据的关系数据库管理系统 MongoDB用于文件(通过GridFS)和其他数据clob/JSON/etc 下一步是授权。仅仅基于角色的授权是不够的,因为应该允许/不允许用户查看/修改不同的资源。虽然我想到了ACL 最常见的简单ACL表可能如下所示: TABLE | FIELDS -------+-------------- class | id, className object | id, cl
- 主要数据的关系数据库管理系统
- MongoDB用于文件(通过GridFS)和其他数据clob/JSON/etc
TABLE | FIELDS
-------+--------------
class | id, className
object | id, class_id, objectId
acl | id, object_id, user_id, permissionBitMask (crud)
但不幸的是,这还不足以满足我的需要
我还需要:
- 角色:
- 每个用户可以有多个角色,并且
- ACL条目也可以属于角色
- 更多权限:
- 例如:每个项目可以有多个任务,但是不允许修改项目详细信息的用户为此项目创建新任务。因此必须有单独的权限
- 不同类型的ObjectId:
- RDBMS表将使用UUID代理键(因此,至少我不必在这里处理复合键)
- 但是MongoDB当然使用自己的ObjectId
- 此外,我将在代码中包含一些静态资源,这些资源也必须受到访问限制
- 父对象继承权限
TABLE | FIELDS
---------------+--------------
class | id, className
object | id, class_id, objectId, parent_object_id
acl | id, object_id, user_id, role_id
permission | id, permissionName
acl_permission | id, acl_id, permission_id, granted
当然,我可以将acl
表拆分为两个表(1.对象+用户,2.对象+角色),但我认为这并不重要
“objectId”将是一个简单的VARCHAR,我的应用程序必须将其从/转换为字符串。否则,我将为不同的objectId类型提供5个额外的表。这将导致5个额外的连接操作
现在,基本的查找查询如下所示:
SELECT p.granted
FROM acl a
JOIN acl_permission p
WHERE p.permission_id = ?
AND (
a.object_id = ? AND a.user_id = ?
OR a.object_id = ? AND a.role_id IN (?)
)
(将缓存权限,当前用户的角色也将通过会话上下文缓存。已授予
仅指示用户是否具有权限。)
然后,如果当前对象没有ACL条目,我还必须应用递归选择来获取父对象的ACL
这不可能真正实现。那么有什么替代方案呢?我的想法:
- 不同的数据库模式(有什么想法吗?)
- 像Neo4j这样的图形数据库
- 对于该数据库来说,查找具有权限项的第一个父级是一项简单的任务
- 在ACL条目中存储权限数组是可能的
无连接->
- 基本上,我可以在单个节点中存储所有信息:
权限:[{Permission1:true},{Permission2:false}]
)
当然,也可以将权限和类存储为单独的节点并将它们链接在一起,但我不知道使用Neo4j的更好方法是什么
对此有什么想法吗?有现成的解决方案吗?也许有理由将MongoDB用于ACL
我读过关于XACML和OAuth(2)的文章,但它们似乎都需要一个额外的ACL模式来完成我所需要的工作。或者我错了吗?首先,您正在寻找的复杂权限系统有一个名为(基于角色的访问控制)的标准规范。我用SQL实现了各种RBAC模型,包括简单的和复杂的。工作正常,当关系数增长超过百万时,SQL在商品硬件上的实现速度不快。读取是即时的,但由于复制记录以提供快速读取的繁重工作,写入速度较慢 最初,当我设计权限系统时,我根据RBAC规范在一张纸上“绘制”了它。输出实际上是一个图形。因此,经过两年的生产使用,我正在考虑切换到本机图形数据库 Neof4j是一个流行的解决方案,但是一些重要的客户似乎不满意它,因为它的集群和复制系统很弱
您在上面提到“不可能在Neo4j数组中存储复杂类型”。OrientDB自夸已经用自定义数据类型解决了这个问题。我个人还没有尝试过,但计划在迁移生产数据后进行测试。请参阅关于Neo4j google group的讨论:
{
class: ClassName,
object: ObjectId,
parent: RelationToParentNode,
user: UserId,
role: RoleId,
grantedPermissions: [Permission1, Permission2, ...]
}