11.2 使用 Keycloak 管理用户帐户

在上一节中,我们基于登录表单向 Edge Service 添加了用户身份验证。您尝试通过在启动时在内存中自动生成的用户帐户登录。这对于第一次使用 Spring Security 进行实验是可以的,但这不是您在生产环境中想要做的事情。

作为最低要求,我们需要用户帐户的持久化存储和注册新用户的选项。应特别关注使用强加密算法存储密码,并防止对数据库的未经授权访问。鉴于此功能的重要性,将其委托给专用应用程序是有意义的。

Keycloak(www.keycloak.org)是一个开源身份和访问管理解决方案,由 Red Hat 社区开发和维护。它提供了广泛的功能集,包括单点登录(SSO)、社交登录、用户联合、多因素身份验证和集中用户管理。Keycloak 依赖于 OAuth2、OpenID Connect 和 SAML 2.0 等标准。目前,我们将使用 Keycloak 来管理 Polar Bookshop 中的用户帐户。稍后我将向您展示如何使用其 OpenID Connect 和 OAuth2 功能。

注意 Spring Security 提供了实现用户管理服务所需的所有功能。如果您想了解更多关于此主题的信息,可以参考 Laurentiu Spilca 的《Spring Security in Action》(Manning,2020)的第 3 章和第 4 章。

您可以在本地将 Keycloak 作为独立 Java 应用程序或容器运行。对于生产环境,有一些解决方案可以在 Kubernetes 上运行 Keycloak。Keycloak 还需要关系数据库进行持久化。它附带一个嵌入式 H2 数据库,但您希望在生产环境中将其替换为外部数据库。

对于 Polar Bookshop,我们将在本地将 Keycloak 作为 Docker 容器运行,依赖嵌入式 H2 数据库。在生产环境中,我们将使用 PostgreSQL。这似乎与环境一致性原则相矛盾,但由于它是第三方应用程序,测试其与数据源的交互不是您的责任。

本节将逐步指导您完成 Polar Bookshop 用例的 Keycloak 配置。首先,打开您的 polar-deployment 仓库。然后在 docker/docker-compose.yml 中定义一个新的 polar-keycloak 容器。

清单 11.3 在 Docker Compose 中定义 Keycloak 容器

version: "3.8"

services:
 ...
 polar-keycloak:
 # 描述 Keycloak 容器的部分
 image: quay.io/keycloak/keycloak:19.0
 container_name: "polar-keycloak"
 command: start-dev
 # 以开发模式启动 Keycloak(使用嵌入式数据库)
 environment:
 - KEYCLOAK_ADMIN=user
 - KEYCLOAK_ADMIN_PASSWORD=password
 # 定义管理员凭据作为环境变量
 ports:
 - 8080:8080

注意 稍后我将为您提供一个 JSON 文件,您可以在启动 Keycloak 容器时使用它来加载整个配置,因此您无需担心容器的持久化。

您可以通过打开终端窗口、导航到保存 docker-compose.yml 文件的文件夹并运行以下命令来启动 Keycloak 容器:

$ docker-compose up -d polar-keycloak

在我们开始管理用户帐户之前,我们需要定义一个安全领域。我们将在下一节中进行此操作。

11.2.1 定义安全领域

在 Keycloak 中,应用程序或系统的任何安全方面都在领域(realm)的上下文中定义,领域是我们应用特定安全策略的逻辑域。默认情况下,Keycloak 预配置了一个 Master 领域,但您可能希望为构建的每个产品创建一个专用领域。让我们创建一个新的 PolarBookshop 领域来承载 Polar Bookshop 系统的所有安全相关方面。

确保您之前启动的 Keycloak 容器仍在运行。然后打开终端窗口,在 Keycloak 容器内进入 bash 控制台:

$ docker exec -it polar-keycloak bash

提示 Keycloak 可能需要几秒钟才能启动。如果您在启动容器后立即尝试访问它,您可能会收到错误,因为它尚未准备好接受连接。如果发生这种情况,请等待几秒钟然后重试。您可以使用 docker logs -f polar-keycloak 检查 Keycloak 日志。打印出消息 "Running the server in development mode" 后,Keycloak 即可使用。

我们将通过其 Admin CLI 配置 Keycloak,但您也可以通过 http://localhost:8080 提供的 GUI 实现相同的结果。首先,导航到 Keycloak Admin CLI 脚本所在的文件夹:

$ cd /opt/keycloak/bin

Admin CLI 受我们在 Docker Compose 中为 Keycloak 容器定义的用户名和密码保护。在运行任何其他命令之前,我们需要启动一个经过身份验证的会话:

$ ./kcadm.sh config credentials \
 --server http://localhost:8080 \
 # Keycloak 在容器内运行在端口 8080 上
 --realm master \
 # Keycloak 中配置的默认领域
 --user user \
 # 我们在 Docker Compose 中定义的用户名
 --password password
 # 我们在 Docker Compose 中定义的密码

提示 您应该保持当前终端窗口打开,直到完成配置 Keycloak。如果在任何时候经过身份验证的会话过期,您总是可以通过运行前面的命令来启动新会话。

此时,您可以继续创建一个新的安全领域,所有与 Polar Bookshop 关联的策略都将存储在其中:

$ ./kcadm.sh create realms -s realm=PolarBookshop -s enabled=true

11.2.2 管理用户和角色

我们需要一些用户来测试不同的身份验证场景。正如第 2 章中所预期的,Polar Bookshop 有两种类型的用户:客户和员工。

  • 客户可以浏览书籍并购买它们。
  • 员工还可以向目录中添加新书籍、修改现有书籍和删除它们。

为了管理与每种用户类型关联的不同权限,让我们创建两个角色:customeremployee。稍后,您将基于这些角色保护应用程序端点。这是一种称为基于角色的访问控制(RBAC)的授权策略。

首先,从您迄今使用的 Keycloak Admin CLI 控制台在 PolarBookshop 领域中创建两个角色:

$ ./kcadm.sh create roles -r PolarBookshop -s name=employee
$ ./kcadm.sh create roles -r PolarBookshop -s name=customer

然后创建两个用户。Isabelle Dahl 将是书店的员工和客户(用户名:isabelle)。您可以按如下方式为她创建帐户:

# 用户应该是活动的
$ ./kcadm.sh create users -r PolarBookshop \
 -s username=isabelle \
 # 新用户的用户名。它将用于登录
 -s firstName=Isabelle \
 -s lastName=Dahl \
 -s enabled=true

$ ./kcadm.sh add-roles -r PolarBookshop \
 --uusername isabelle \
 --rolename employee \
 # Isabelle 既是员工也是客户
 --rolename customer

然后为 Bjorn Vinterberg(用户名:bjorn)执行相同的操作,他是书店的客户:

# 用户应该是活动的
$ ./kcadm.sh create users -r PolarBookshop \
 -s username=bjorn \
 # 新用户的用户名。它将用于登录
 -s firstName=Bjorn \
 -s lastName=Vinterberg \
 -s enabled=true

$ ./kcadm.sh add-roles -r PolarBookshop \
 --uusername bjorn \
 --rolename customer
 # Bjorn 是客户

在真实场景中,用户将自己选择密码,最好启用双因素身份验证。Isabelle 和 Bjorn 是测试用户,因此分配显式密码(password)是可以的。您可以从 Keycloak Admin CLI 执行此操作:

$ ./kcadm.sh set-password -r PolarBookshop \
 --username isabelle --new-password password
$ ./kcadm.sh set-password -r PolarBookshop \
 --username bjorn --new-password password

用户管理就到此为止。您可以使用 exit 命令退出 Keycloak 容器内的 bash 控制台,但请保持 Keycloak 运行。

接下来,让我们探讨如何改进 Edge Service 中的身份验证策略。

results matching ""

    No results matching ""