过去我会使用以下简单数据模型来实现我的应用程序的安全性。我会有 隐式拒绝,显式允许和显式拒绝 ,后者可以覆盖它之前的那个。
我现在面临的问题是我当前的应用程序需要可扩展到数千万条记录。在上面的数据模型中,对于每条记录,我可能有许多ACL条目。因此,如果我的记录表(acltest_uspaceData)有1000万行,我的acl安全表可能会有更多。
这是我们计划存储的记录数量的合适数据模型吗?如果没有,我该如何对此数据模型进行扩展?
我正在使用PostGIS作为数据库。
答案 0 :(得分:1)
根据您的安全规则,acltest_role_acl.allowed
看起来多余 - 如果存在角色ACL条目,则可以隐含allowed == true
。当然,除非你真的想要“撤销”整个群体而不仅仅是个人用户。
除此之外,您的模型看起来很好,您应该专注于将其有效地存储在数据库中。
如果您的DBMS支持它,将ACL存储为clustered table可能是个好主意:
{record_id, user_id}
,对于角色应为{record_id, role_id}
访问控制列表。{user_id, record_id}
和{role_id, record_id}
)。如果您的DBMS支持它,您可以压缩聚类索引的前沿(在Oracle下,这称为COMPRESSED INDEX ORGANIZED表)。这将消除由重复ACL产生的一些冗余(来自您的评论:“通常有许多人具有相同的权限”和“有许多行具有相同的权限”)。
另一方面,如果你主要担心存储成本(和/或使用不支持压缩的DBMS),但不介意增加复杂性和潜在的性能影响,你可以考虑这样的事情:
由于许多记录共享相同的ACL(根据您的评论),因此该模型可以避免大部分重复。
例如,如果N条记录具有相同的5个ACL条目:
acltest_uspaceData.acl_group_id
)。问题是:当您插入新记录时,如何找到“匹配”ACL组?这可以大致像这样解决,但不会非常有效:
SELECT *
FROM acltest_aclGroup
WHERE
NOT EXISTS (
SELECT user_id, allowed
FROM acltest_users_acl
MINUS -- Or EXCEPT, depending on the DBMS.
SELECT user_id, allowed
FROM <user_acl_tmp>
)
AND NOT EXISTS (
SELECT user_id, allowed
FROM <user_acl_tmp>
MINUS
SELECT user_id, allowed
FROM acltest_users_acl
)
AND NOT EXISTS (
SELECT role_id
FROM acltest_role_acl
MINUS
SELECT role_id
FROM <role_acl_tmp>
)
AND NOT EXISTS (
SELECT role_id
FROM <role_acl_tmp>
MINUS
SELECT role_id
FROM acltest_role_acl
)
首先,为用户和角色ACL(<user_acl_tmp>
和<role_acl_tmp>
)创建一个临时表,然后插入新记录应该包含的ACL条目,然后执行上面的查询,搜索现有ACL组,用于设置与临时ACL的相等性。
答案 1 :(得分:0)
我不是这个主题的权威,但是我所知道的为该国最大的CDN提供商之一开发云平台服务的人强烈赞成OpenLDAP在可扩展性受到关注的情况下。我不确定它是否会处理您的ACL要求,但是应该进行一些研究。