如何使用hibernate过滤器或其他方式在spring数据jpa中实现行级安全性?

ali*_*ani 9 spring hibernate row-level-security spring-security spring-data

信息软件中一个非常重要的问题是具有不同职责和访问级别的不同角色的用户的存在.例如,想象一下具有如下结构(层次结构)的组织:

[Organization Role ]     [Organization ID]
 CEO                        org01
   Financial Assistant      org0101
           personnel 1

   Software Assistant       org0102
           personnel 2

   Commercial Assistant     org0103
           personnel 3
Run Code Online (Sandbox Code Playgroud)

想象一下,该组织有一个管理人员信息的系统.在该系统中显示人员信息的规则是每个用户都可以看到他有权访问的组织的人员信息; 例如,'user1'可以访问'财务助理'和'商务助理'级别,因此他只能看到'人员1'和'人员3'的信息.同样,'user2'只能访问'Commercial Assistant'级别,因此他只能看到'人员3'的信息.因此,该系统中的每个用户都具有特定的访问级别.现在考虑在这个系统中,每个用户只能看到他登录后可以访问的人员信息.具有这个系统的表结构是这样的:

[Organization]
id
code
name

[Employee]
id
first_name
last_name
organization_id

[User]
id
user_name
password

[UserOrganization]
user_id
organization_id
Run Code Online (Sandbox Code Playgroud)

以下查询足以获得每个用户的正确人事信息结果:

select *

from employee e 

where e.organization_id in

(select uo.organization_id

 from user_organization uo

 where uo.user_id=:authenticatedUserId)
Run Code Online (Sandbox Code Playgroud)

我们可以看到,以下条件定义了显示正确数据的访问逻辑:

e.organization_id in

(select uo.organization_id

 from user_organization uo

 where uo.user_id=:authenticatedUserId)
Run Code Online (Sandbox Code Playgroud)

这种访问级别也称为"行级安全性"(RLS).另一方面,相应的存储库类可能有几个负责读取数据的方法,所有这些方法都必须满足适当的访问级别条件.在这种情况下,访问级别条件将在某些地方(方法)重复.似乎使用'休眠过滤器'将是解决此问题的正确方法.唯一需要的是一个过滤器,它获取经过身份验证的用户的id,并在每个读取方法之前执行'enablefilter'命令.

@Filters( {
  @Filter(name=“EmployeeAuthorize", condition="(organization_id in (select uo.organization_id from user_organization uo where uo.user_id=:authenticatedUserId) )  ")
} )
Run Code Online (Sandbox Code Playgroud)

现在的问题是,提议的解决方案是对的吗?如果是,如何在弹簧数据中使用此方法?PS:鉴于我们不想依赖数据库,数据库端的实现不能成为候选解决方案,因此我们不得不在应用程序端(级别)实现它.

Eug*_*gen 5

阿里,那是一个有趣的场景。

两个问题需要回答在这里。

第一个问题 -公开数据时,系统只是要进行过滤还是要超越呢?例如,如果您公开类似users / {id}之类的操作-那么您需要检查授权-并确保用户有权访问该操作。如果仅公开/ users之类的操作,则只需过滤即可,因为您将公开当前用户有权查看的用户。这种区别将决定很多实现。


第二个问题是-您可以从事多少体力劳动?

一方面,您可以使数据适应框架的需要-并尝试尽可能多地依赖内置功能(安全性表达式,ACL)。或者,另一方面,您可以使代码适应数据的结构-并手动进行操作。

这是我首先要关注的两个因素,因为根据这四个决定,实现看起来会完全不同。


最后,回答您的“可以ACL缩放”问题-两个快速注释。一-您需要测试。是的,ACL可以扩展,但是可以扩展到10K或100K,这是一个没有测试就可以具体回答的问题。

其次,当您进行测试时,请考虑实际情况。了解解决方案的局限性当然很重要。但是,除此之外,如果您认为您的系统将拥有1M个实体,那就太好了。但是,如果不这样做,那就不要将其作为目标。

希望能有所帮助。