当前位置: 首页 > 面试题库 >

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

邵昆琦
2023-03-14
问题内容

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

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

   Software Assistant       org0102
           personnel 2

   Commercial Assistant     org0103
           personnel 3

想象一下,这个组织有一个管理人员信息的系统。在此系统中显示人员信息的规则是,每个用户都可以看到他有权访问的组织的人员信息;例如,“用户1”有权访问“财务助理”和“商业助理”级别,因此他只能看到“人员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

下面的查询足以为每个用户获取正确的人员信息结果:

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,并在每个read方法之前执行
enablefilter”命令。

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

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


问题答案:

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

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

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

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

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

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

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

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

希望能有所帮助。



 类似资料:
  • 问题内容: 可以说我有两个实体 我现在想要的是,当我获取EntityA时,我想添加一个where子句以获取所有modelPercent大于0的EntityB。 我不想使用过滤器,因为此要求仅适用于这种特殊情况。 例如数据: 我需要一种方法,可能是获取EntityA的hql,以便当我说EntityA.getEntityBList()时,它应该仅返回1条记录(一个模型百分比为10(大于零的记录))。

  • 问题内容: 我想在hibernate中实现类似于触发器的功能。 我需要的是当表中的列达到特定值时,应在另一张表中插入一行,或者应更新某些其他表。 如何在hibernate状态下实现呢? 问题答案: 这在第14章中进行了描述。 例如,您可以拦截更新后事件。 但是,将事件系统用于 业务 运营可能不是最好的主意(它们最适合用于基础结构问题)。您应该为此使用更高级别的层。

  • 正如标题所说。 非常感谢你的帮助。

  • 问题内容: 我正在使用Struts 2.2.1.1和Hibernate 3.6.2.Final。我还将C3P0用于在Tomcat 7.0.11上运行的连接池。 我遇到的问题是无法关闭我的Hibernate会话,并且我很快超过了“ hibernate.c3p0.max_size”属性中配置的最大打开连接数。 我认为这是因为我的hibernate会话已打开但从未关闭。我正在从存储在ServletCon

  • 问题内容: 我有一个基本上从表中返回全部数据的函数。我该如何实现批量提取,以便一次将批量返回60,000行返回数据。 以下逻辑适用于这种情况吗? http://javainnovations.blogspot.com/2008/07/batch-insertion-in- hibernate.html 问题答案: 在中,使用参数设置批量大小

  • 众所周知,WebSecurityConfigurerAdapter类已被弃用。 我试图在filterChain中实现customFilter,但我遇到了一个与新的AuthenticationManager相关的问题。 问题是这样的: 如您所见,身份验证管理器需要AuthenticationConfiguration类作为NotNull参数,没有它,我无法创建CustomAuthentication