Spring Boot控制器中基于用户授权的动态字段暴露

问题描述 投票:0回答:1

我开发了一个 Spring Boot 应用程序,其中有一组连接到公共服务层的控制器。我不介意使用任何协议(

REST,
GraphQL
gRPC
等)来进行控制器和客户端之间的通信。以下是架构概述:

控制器与服务通信以检索数据。 根据用户的授权级别,我想在发送回之前修改响应数据。

例如:

  • 如果用户是管理员,他们应该看到其他用户的所有字段,例如

    username
    address

  • 如果用户是普通用户,他们不应该看到像其他人的

    username
    address
    这样的敏感字段。

现在,我的挑战是:

  1. 统一服务层:我希望保持服务层在多个控制器之间通用和可重用,但在每个控制器中应用不同的授权规则。
  2. 多个授权级别:不同的控制器之间可能有不同的授权级别,我需要一个解决方案,允许我以干净且可维护的方式进行调整。
  3. 动态字段暴露:我需要一种机制,根据用户的授权级别动态调整返回给客户端的字段。

我如何构建架构以便:

  • 控制器根据用户角色或授权类型进行划分,但它们都连接到相同的底层服务。
  • 每个控制器仅根据用户的授权返回相应的字段。

您是否会建议任何与 Spring Boot 配合良好的模式或实践? 示例:

考虑一个返回具有以下字段的 User 对象的服务方法:

public class User {
    private String username;
    private String address;
    private String email;
    private String phone;
    // getters and setters
}

如果调用 API 的用户是管理员,他们应该收到完整的 User 对象:

{
  "username": "morteza.j8",
  "address": "Mashhad",
  "email": "[email protected]",
  "phone": "09123456789"
}

但是如果用户是普通用户,则响应应仅包含字段的子集:

{
  "email": "[email protected]",
  "phone": "09123456789"
}

如何跨多个控制器和服务以最有效且可维护的方式实现此字段过滤? 谢谢!

java spring-boot design-patterns spring-security authorization
1个回答
0
投票

您希望根据访问该 URL 的用户的权限从同一 URL 获取不同的实体。这从根本上违背了 REST 哲学,即您的请求应该是无状态的。如果这样做,您将遇到缓存问题。由于 GET 请求是幂等的,它们几乎总是由中间件缓存,因此您会遇到这样的情况:用户在没有缓存的情况下检索数据可能会看到他们无权访问的信息。

© www.soinside.com 2019 - 2024. All rights reserved.