[Organization Role ] [Organization ID]
CEO org01
Financial Assistant org0101
personnel 1
Software Assistant org0102
personnel 2
Commercial Assistant org0103
personnel 3
想象一下,这个组织有一个管理人员信息的系统。在这个系统中,显示人员信息的规则是每个用户只能看到他所拥有访问权限的组织的人员信息;例如,“user1”可以访问“财务助理”和“商业助理”级别,因此他只能看到“personnel 1”和“personnel 3”的信息。同样,“user2”只能访问“商业助理”级别,因此他只能看到“personnel 3”的信息。因此,该系统中的每个用户都有特定的访问级别。 现在考虑,在该系统中,每个用户登录后只能看到他所拥有访问权限的人员信息。假设该系统的表结构如下:
[Organization]
id
code
name
[Employee]
id
first_name
last_name
organization_id
[User]
id
user_name
password
[UserOrganization]
user_id
organization_id
以下查询足以获取每个用户的正确人员信息结果:
select *
from employee e
where e.organization_id in
(select uo.organization_id
from user_organization uo
where uo.user_id=:authenticatedUserId)
正如我们所看到的,下面的条件定义了显示正确数据的访问逻辑:
e.organization_id in
(select uo.organization_id
from user_organization uo
where uo.user_id=:authenticatedUserId)
这种访问级别也被称为“行级安全”(RLS)。 另一方面,相应的存储库类可能有几个负责读取数据的方法,所有这些方法都必须满足适当的访问级别条件。在这种情况下,访问级别条件将在某些地方(方法)重复出现。似乎使用“Hibernate过滤器”是解决此问题的适当方法。唯一需要的是一个过滤器,它获取经过身份验证的用户的ID,并在每个读取方法之前执行“enablefilter”命令。
@Filters( {
@Filter(name=“EmployeeAuthorize", condition="(organization_id in (select uo.organization_id from user_organization uo where uo.user_id=:authenticatedUserId) ) ")
} )
现在的问题是,所提出的解决方案是否正确?如果是,如何在Spring Data中利用这种方法? 附注:鉴于我们不想依赖数据库,因此在数据库端实现不能成为候选解决方案,出于这个原因,我们被迫在应用程序端(层)实现它。