【问题标题】:Fetch data from database according to the permissions根据权限从数据库中获取数据
【发布时间】:2020-10-05 18:02:42
【问题描述】:

我正在开发一个应用程序,我需要在其中开发基于角色的访问控制。 我试过寻找其他答案,但这些提供了一些不同的解决方案。根据我们应用程序中的模块,角色是动态的,但权限是静态的。

这是我的场景。

我有员工和医生,员工与医生相连。 所以权限是"View Physician", "Edit Physician", "View Appointment", "Edit Appointment"

员工也可以是全局用户,也可以是本地用户。所以假设一个员工是一个全局用户,他对每个医生都有权限。 如果工作人员是本地用户,则他对特定医师具有权限。

现在当员工进入预约列表时,api应该根据他的权限返回数据,他应该只能看到那些授予他“查看预约”权限的医生的预约列表

使用hasRolehasAuthority,我可以限制完整的API,但我需要根据权限从数据库中获取数据。 在 JPA 查询中为每个 db 命中硬编码权限会太多。

因此,我正在为此寻找有关架构或设计模式的一些建议和帮助。

【问题讨论】:

    标签: java spring spring-security authorization system-design


    【解决方案1】:

    嗯,你的问题确实很广泛,但我试着回答一下......

    对于这种情况,spring security 是您可以根据为用户定义的角色控制任何 API 访问的最佳方式

    WebSecurityConfigurerAdapter 类的

    configure 方法为用户配置其特定角色并根据角色映射 URL 模式

    记住 WebSecurityConfigurerAdapter 类 具有三个版本的 configure 方法,但对于这种情况,您只需要其中两个版本,一个用于映射用户,即 configure(AuthenticationManagerBuilder auth) 与他们的特定角色和一个用于映射 url 模式与他们的特定角色即 configure(HttpSecurity http)

    因此,通过将 url 映射到特定角色,您可以根据用户角色轻松控制 API 调用,因此 JPA 查询不需要角色的硬编码

    我分享一个示例,您如何根据角色映射 url

    protected void configure(HttpSecurity http){
       http.authorizeRequests()
                .antMatchers("/")
                .hasRole("Physician")
                .and()
                .formLogin()
    

    注意您也可以使用任何其他方式登录

    我希望这将有助于并激励您探索该主题。

    【讨论】:

      【解决方案2】:

      根据不同查询用例的需求,我会相应地使用不同的策略:

      1. 对于返回单个记录的用例(例如通过 ID 查找记录),SQL 查询不应该知道用户权限。从数据库中获取数据后,使用@PostAuthorize 进行应用级安全检查。

      2. 对于返回记录列表的用例,允许用户配置偏移或限制等内容(即分页用例),SQL 查询知道用​​户权限,这意味着我们需要添加必要的基于用户权限的 SQL 查询的 where 子句。

        这主要是因为数据集很大时的性能以及使用@PostFilter在应用程序端完成时的困难。

        例如,考虑这样一种情况,如果您需要获取允许用户查看的第 5200 到第 5400 条记录,但不允许在 SQL 查询中添加任何基于用户权限的 where 子句,您将如何解决?如果所有安全检查都在应用程序端完成,这个问题?我只能想象代码会非常混乱而且效率不高,即使我正确实现它....

      3. 对于返回记录列表但用户无法配置偏移或限制等内容的用例,我将使用与(1)相同的策略,但这次使用@PostFitler

      所以除非有特殊原因,如(2),总体目标是尽可能将安全逻辑视为横切关注点,使核心域逻辑代码不知道它的存在。安全性代码应该集中在一个地方/包/模块等,但不能分散在所有代码中。这基本上意味着我们使用spring security提供的AOP技术,在查询方法执行完成后,对返回的对象执行一些安全检查代码。

      【讨论】:

      • 但在这种方法中。假设有预约列表页面,我有 2 位医生的本地许可,没有其他医生的许可。所以当我打开预约列表时,api 应该只返回这 2 位医生的数据。
      • 我不知道您的查询用例要求是什么......正如我已经提到的,如果它是一个分页查询,用户需要在请求中指定偏移量/限制类型的东西,请使用策略 2并使用正确的 where 子句动态构造 SQL 以获得应该对用户可见的正确数据。
      猜你喜欢
      • 1970-01-01
      • 2017-10-26
      • 1970-01-01
      • 2012-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-22
      相关资源
      最近更新 更多