Spring 安全性:如果用户与实体没有关系则拒绝访问的最佳方法

Spring Security: Best approach to deny access if a user doesn't have a relation with the entity

我不确定如何 google 这个“问题”,所以我创建了这个问题。

我正在构建的应用程序具有以下数据库结构(针对示例进行了简化)。

- Lab1
    - Users    
       - User1
       - User2
    - Products
       - Product1
- Lab2
    - Users 
       - User3
    - Products
       - Product2

Endpoints:
 - ../{labId}/products
 - ../products/{id}
 - ../{labId}/a
 - ../{labId}/b
 - ../{labId}/c
 - ../{labId}/d
 - ../{labId}/...

用户应该只能访问他分配到的实验室中的数据。用户 3 应该无法从产品 1 获取产品数据。

我创建了一个查询数据库的函数,以检查用户是否确实与请求的实验室相关联,但我必须在每个端点上调用此函数。这将导致此函数每分钟被调用一千次,因为用户所做的每个查询都将与实验室相关联。这也造成了很多重复代码。

该应用程序目前通过使用 spring 安全和 JWT 来保护,并且还具有 RBAC 来拒绝某些用户访问某些资源。

有没有办法使用注释来解决这个问题,是我的数据库结构不是最优的还是我的方法正确?

非常感谢!

编辑:端点的示例屏幕截图,productrepository 是一个基本的 JPA 存储库。

我担心的是 getLabAssociatedWithEntity / userBelongsToLab 方法的重复,想知道​​这是否是不好的做法。

@GetMapping("/{id}")
fun getProductById(@PathVariable id: Long): ResponseEntity<Product> {
    val lab = getLabAssociatedWithProduct(id)
    if (userBelongsToLab(SecurityContextHolder.getContext().authentication.name, lab.id)) {
        return ResponseEntity.ok().body(productService.getProductById(id))
    }
    return ResponseEntity(HttpStatus.UNAUTHORIZED)
}

 Productservice
 fun getProductById(id: Long): Product {
    return productRepository.findById(id).orElseThrow { ResourceNotFoundException("Product not found with id: $id") }
}

我认为您可以在用户和产品之间建立关联:

class User{
   Lab lab
   }

和产品 class 您可以拥有:

class Product{
   Lab lab;
}

class Lab{
   List<Product> productList
}

我没有添加注释,但想法是这样的,所以如果你有一个特定的用户实例,User1,如果用户属于一个实验室,而一个实验室有产品,首先你可以得到实验室的用户然后查询该实验室的产品(延迟加载)

我决定通过缓存请求以查看用户是否与实验室相关联来解决此问题。这样它就不会减慢应用程序的速度。