Spring Security OAuth 2 教程 - 6:微服务项目设置

在之前的文章中,我们学习了使用 Web 浏览器、cURL 和 Postman 进行各种 OAuth 2.0 / OpenID Connect Flow。现在是时候学以致用了。

在使用像 Spring Security 这样的安全框架实现基于 OAuth 2.0 / OpenID Connect 的 Security 时,许多活动都是由框架在幕后执行的。了解框架内部发生的情况非常重要,这样我们才能有效地使用框架。

在本文中,我将简要介绍我们将在 Spring Security OAuth 2 教程系列中使用的基于微服务的示例项目。

示例 Spring Boot 微服务项目

我们将构建一个包含以下组件的微服务示例项目:

  • Authorization Server - 这是 OAuth 2.0 授权服务器,将向客户端发放访问令牌。我们将使用 Keycloak 作为授权服务器。
  • messages-webapp - 终端用户将使用的基于 Spring MVC 的客户端应用。
  • messages-service - Spring Boot REST API(资源服务器)用于管理用户数据(消息),并将由 messages-webapp 应用使用。
  • archival-service - Spring Boot 应用可使用定时任务定期处理消息存档。它还提供了一个 API 端点来触发存档过程。该服务将同时扮演资源服务器和客户端的角色。

OAuth2 微服务架构

让我们来了解一下这些组件各自提供的功能。

messages-webapp(客户端)

这是一个使用 Spring MVC 和 Thymeleaf 渲染用户界面的 Spring Boot Web 应用。该应用将受到授权服务器(Keycloak)的保护,并将使用 “授权码模式” 来认证用户身份并获取访问令牌。

  • 任何人(包括未经授权的用户)都可以查看消息列表。
  • 任何经过认证的用户都可以发布新消息。
  • 任何具有 ADMIN 角色的认证用户都可以触发消息存档流程。

messages-service(资源服务器)

这是一个 Spring Boot REST API,用于管理用户数据(消息),并将由 messages-webapp 应用使用。这是一个资源服务器,提供以下 API 端点:

  • GET /api/messages - 返回消息列表。可公开访问,无需认证。
  • POST /api/messages - 创建一条新消息。任何通过身份认证的用户都可以调用此 API 端点。
  • POST /api/messages/archive - 归档超过 N 天的消息。只有具有 ADMINADMIN_JOB 角色的认证用户才能调用此 API 端点。

archival-service(资源服务器 & 客户端)

这是一个 Spring Boot 服务,使用定时任务定期处理消息存档。该服务暴露了一个 API 端点,只有 ADMIN 用户才能触发存档过程。该应用将受到授权服务器(Keycloak)的保护,并将使用 “客户端凭证模式”(Client Credentials Flow)获取访问令牌(access token),以调用 messages-servicePOST /api/messages/archive API 端点。

该服务提供以下 API 端点:

  • POST /api/messages/archive - 在内部将存档流程委托给 messages-service。只有具有 ADMIN 角色的认证用户才能调用此 API。

为什么 messages-webapp 不直接调用 messages-service POST /api/messages/archive 端点?

原因是,我想演示一个服务同时充当资源服务器和客户端的场景。archival-service 是一个资源服务器,提供 POST /api/messages/archive API 端点,同时也是 messages-service 的客户端。

Keycloak 设置

在前面的文章中,我们已经学习了如何设置 Keycloak 并创建 Realm、客户端和用户。我们将在服务配置中使用类似的 Keycloak 设置。

导出和导入 Keycloak Realm 配置

如果由于某种原因删除了 keycloak docker 容器,我们就需要再次手动创建 Realm、客户端和用户。我们可以使用 Keycloak 的导出和导入功能来导出 Realm 配置,并在需要时将其导入。

一旦 keycloak 实例启动并运行,我们就可以创建 Realm、客户端和用户,然后使用以下步骤导出 Realm 配置。

$ docker ps
# 复制 keycloak 容器 id

# 通过 ssh 进入 keycloak 容器
$ docker exec -it <container-id> bash

# 导出 Realm 配置和用户信息
$ /opt/keycloak/bin/kc.sh export --dir /opt/keycloak/data/import --realm sivalabs --users realm_file

# 推出容器
$ exit 

# 将导出的 Realm 配置复制到本地计算机上
$ docker cp <container-id>:/opt/keycloak/data/import/sivalabs-realm.json ~/Downloads/sivalabs-realm.json

导出 Realm 配置文件后,将其复制到示例项目的 realm-config 文件夹中。然后,你就可以使用 docker-compose 自动导入它了,方法如下:

version: '3.8'
name: spring-security-oauth2-microservices-demo
services:
  keycloak:
    image: quay.io/keycloak/keycloak:22.0.3
    command: ['start-dev --import-realm']
    volumes:
      - ./realm-config:/opt/keycloak/data/import
    container_name: keycloak
    hostname: keycloak
    environment:
      - KEYCLOAK_ADMIN=admin
      - KEYCLOAK_ADMIN_PASSWORD=admin1234
    ports:
      - "9191:8080"

如果还有什么不清楚的地方,不要担心,我将在接下来的文章中详细介绍这个示例项目。

总结

在本文中,我们学习了本 Spring Security OAuth 2 教程系列中的微服务示例项目。在下一篇文章中,我们将详细介绍如何创建 messages-webapp 应用、设置 Keycloak 进行访问控制。


参考:https://www.sivalabs.in/spring-security-oauth2-tutorial-microservices-project-setup/