我有一个场景的"最佳实践"问题.
场景:数据库中的多个实体,例如Document,BlogPost,Wiki可以由个人共享.不是为每个实体创建共享表,而是创建单个共享表.问题是,如何使用不同的实体映射共享表?
我有三个选项,请告知哪个选项最好,以及是否有更好的选择.
选项1: 创建表共享为:
SHARES
id (unique)
entityId (non DB enforced FK to DOCUMENTS, WIKIS, POSTS etc.)
entityType
sharedBy
sharedWith
sharedDate
Run Code Online (Sandbox Code Playgroud)
这里,entityId将是documentId,wikiId,postId等的FK,entityType将识别entityId的类型.
在创建共享到实体映射时,这在Hibernate建模中存在问题,例如share.getDocument()或share.getWiki()等.
选项2: 创建仅包含共享信息的表共享,然后创建将共享绑定到实体的解析表.
SHARES
id(PK)
sharedBy
sharedWith
sharedDate
shareType (helper field for searches)
SHARES_DOCUMENTS
share_id (unique ID and FK, one to one with SHARES)
document_id (FK to DOCUMENTS)
SHARES_POST
share_id (unique ID and FK, one to one with SHARES)
post_id (FK to POSTS)
more share tables here.
Run Code Online (Sandbox Code Playgroud)
因此,hibernate明智地,Share可以为每个共享类型一对一(例如share.getDocument(),share.getPost(),并且shareType将标识哪个关系是'活动')
选项3 与选项1类似,但创建单个列而不是实体ID
SHARES
id (unique ID)
documentId (FK to …Run Code Online (Sandbox Code Playgroud) 我正在考虑为我们的项目实施Spring ACL,这是非常严格且细粒度的安全性要求。我想知道某种情况是否可能。
基于Spring的ACL文档,可以为任何对象(ACL_OBJECT_IDENTY)授予ACL_SID的权限,并且该文档谈到SID是“主要” ..即当前登录的用户。
因此,如果我将四个部门(D1,D2,D3,D4)分配给两个经理(M1,M2),则M1可以管理D1和D2,M2可以管理D3和D4。我可以使用ACL轻松实现。
现在,我有一个这样的场景,其中部门有员工E1,E2 ...... E8(假设每个部门依次有两个员工,例如D4有E7和E8)。员工提交报告R *,我需要保护对以下报告的“读取”访问权限:1.员工本身。2.员工部门的经理。3.部门的其他员工。
和“管理员”对以下报告的访问权限:1.员工本身2.员工部门的经理。
通过对ACL的原始理解,甚至可以做到这一点,其中“本金”仅限于用户,例如E *或M *。如:
E1, E2.. E8
M1, M2..
Run Code Online (Sandbox Code Playgroud)
对于每个报告,我们可以创建ACL_ENTRY,例如:
R1 read, write to E1 //E1 is author
R1 read, write to M1 //M1 is manager of D1, and E1 belongs to D1
R1 read to E2 //E2 belongs to D1
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我将检查是否有任何E *或M *可以访问R1。
一切都很好,但是我觉得如果E进出D或添加/删除M来管理D的话,管理(ACL条目)会变得太复杂了。
因此,问题是:我可以使用实体对象作为主体,并在需要评估权限时使用该对象来验证权限。因此,我可以在ACL_SID中添加以下内容:
D1, D2, D3 and D4 //departmetnIds, not usersIds
Run Code Online (Sandbox Code Playgroud)
然后将ACL_ENTRIES替换为:
R1 read, write to E1 //E1 is author
R1 read to D1 // note D1 here …Run Code Online (Sandbox Code Playgroud)