如何将用户角色从授权服务器复制到下游微服务?

How can I replicate user roles from an Authorization Server to downstream microservices?

我需要实现一个应用程序,我将在其中使用生成 JWT 令牌的授权服务器。这些令牌将包括授予用户的角色,然后授权用户访问不同的资源。还将有一个网关,其中将添加此安全性。

我的问题是关于用户角色和内部微服务之间的安全性。

创建用户时,他应该被授予一组角色,稍后可能会被授予不同的角色,或者可能会在以后添加新角色。所有这些信息都应该存储在授权服务器中。但是这些信息是如何复制到其他微服务的呢?如果我使用像 Spring Security 这样的框架来保护我的端点,我在其中添加了不同 URL 所需的角色,我是否需要将用户角色硬编码到我在下游微服务中的安全配置中,或者是否有任何其他方式从授权服务器找到它们?

该架构将在 public 网络中使用 API 网关,然后与内部网络中的服务发现进行通信以查找不同的微服务。这些也通过服务发现找到彼此。我使用 Zuul 进行路由。在这种情况下,我还需要保护内部网络中的通信吗?我知道要使用 Spring 安全性进行授权,我无论如何都需要传递 JWT 令牌才能获得用户角色。但否则有必要吗?从客户端到网关使用 HTTPS 并在专用网络中使用不安全的 HTTP 是否足够?

这里有很多选项。

其中之一是您可以将 spring-security-oauth2 与 spring 安全性结合使用。在此设置中,您将区分两种应用程序:

  • 授权服务 (AS) - 此服务发布并验证用于验证客户端身份的访问令牌(例如,使用密码授予或授权代码);
  • 资源服务 (RS) - 例如,它为资源的 CRUD 操作公开了 REST API。端点受到保护。 RS 与 AS 通信以授予访问权限;

在资源服务器中,您将像通常在独立应用程序中那样使用和配置 Spring 安全性。下面是一个非常简单的例子。

这是带有受保护端点的 REST 控制器中的代码:

@PreAuthorize("hasRole('READ_BOOK')")
@GetMapping(value = "/books/{id}")
public ResponseEntity<Book> getBook(@PathVariable("id") String id) {
    ...
    //retrieves book details if you have role READ_BOOK
}

@PreAuthorize("hasRole('WRITE_BOOK')")
@PostMapping(value = "/books")
public Book createBook(@RequestParam("title") String title) {
    ...
    //creates a book if you have role WRITE_BOOK
}

安全配置看起来就像您在编写单体应用程序一样,除了:

  • 您将在配置中添加 @EnableResourceServer 注释;
  • 您将配置 RemoteTokenServices 的实例 - 该服务的任务是根据授权服务器验证提供的令牌并获取用户角色;

AS 将根据某些OAuth2 工作流程颁发访问令牌。客户端将使用这些令牌来访问受保护的端点。

我做了一个小的 PoC(概念验证)设置,我在其中创建了两个简单的应用程序来展示整个过程。请找到它 here 并随时提交问题、建议和 PR。完整的源代码与更多解释捆绑在一起。

请注意,此设置在某些情况下可能会导致过多的服务间通信。我见过一个更复杂的设置,其中 API 网关充当资源服务器,如果用户有足够的凭据,它会用必要的详细信息丰富请求,并将请求传递给基本上信任网关的下游服务。