当前位置: 首页 > article >正文

第2章_保护您的第一个应用程序

第2章_保护您的第一个应用程序

在本章中,您将学习如何使用 Keycloak 保护您的第一个应用程序。为了让事情更有趣,您将运行的示例应用程序由两部分组成,前端 Web 应用程序和后端 REST API。这将向您展示用户如何向前端进行身份验证,以及它如何安全地调用后端。

在本章结束时,您将基本了解 Keycloak 如何利用 OpenID Connect 保护应用程序。

在本章中,我们将介绍以下主要主题:

理解示例应用程序

  • 运行应用程序

  • 了解如何登录应用程序

  • 安全调用后端 REST API

技术要求

要运行本章中包含的示例应用程序,您需要在工作站上安装 Node. js(https://nodejs.org/)。

您还需要拥有与本书关联的 GitHub 存储库的本地副本。如果您安装了 Git,您可以通过在终端中运行以下命令来克隆存储库:

$ git clone https://github.com/PacktPublishing/Keycloak---Identity-and-Access-Management-for-Modern-Applications-2nd-Edition.git

或者,您可以从https://github.com/PacktPublishing/Keycloak—Identity-and-Access-Management-for-Modern-Applications-2nd-Edition下载存储库的 ZIP。

查看以下链接以查看 Code in Action 视频:https://packt.link/oxOr8

了解示例应用程序

示例应用程序由两部分组成 —— 前端 Web 应用程序和后端 REST API。

前端 Web 应用程序是一个用 JavaScript 编写的单页应用程序。由于我们想关注 Keycloak 可以提供什么,因此该应用程序非常简单。此外,为了使运行应用程序尽可能简单,它使用 Node. js。该应用程序提供以下功能:

  • 使用 Keycloak 登录。

  • 显示用户名。

  • 会显示用户的个人资料图片(如果有)。

  • 显示 ID 令牌。

  • 显示访问令牌。

  • 刷新令牌。

  • 调用后端提供的安全端点。

后端 REST API 也很简单,是用 Node. js 实现的。它提供了一个具有两个端点的 REST API:

  • /public:没有安全性的公开可用端点

  • /secured:一个需要具有 myReal 全局角色的访问令牌的安全端点

Node. js 用于示例应用程序,因为我们希望使代码尽可能易于理解和运行,无论您熟悉什么编程语言。

下图显示了前端、后端和 Keycloak 之间的关系。前端使用 Keycloak 对用户进行身份验证,然后调用后端,后端使用 Keycloak 验证是否允许请求:
在这里插入图片描述
图 2.1:应用概述

现在您已经对示例应用程序有了基本的了解,让我们看一些关于这一切是如何结合在一起的更多细节。

当用户单击前端应用程序中的登录按钮时,浏览器将被重定向到 Keycloak 登录页面。然后,用户使用 Keycloak 进行身份验证,然后浏览器使用称为授权码的特殊代码重定向回应用程序。然后,应用程序调用 Keycloak 将授权码交换为以下令牌:

  • ID 令牌:这提供了与经过身份验证的用户有关的应用程序信息。

  • 访问令牌:应用程序在向服务发出请求时包含此令牌,允许服务验证是否应允许请求。

  • 刷新令牌:ID 和访问令牌都有很短的过期时间 —— 默认情况下为 5 分钟。应用程序使用刷新令牌从 Keycloak 获取新令牌。

描述的流程就是 OpenID Connect 中所谓的授权代码流程。如果您还不熟悉 OAuth 2.0 或 OpenID Connect,它们起初可能有点令人生畏,但一旦您熟悉它们,它们实际上非常简单易懂。

为了帮助可视化登录过程,提供了如下简化时序图:
在这里插入图片描述
图 2.2:简化的 OpenID Connect 中的授权代码流程

此图中的步骤如下:

  1. 用户点击登录按钮。

  2. 应用程序重定向到 Keycloak 登录页面。

  3. Keycloak 登录页面显示给用户。

  4. 用户填写用户名和密码并将结果提交给 Keycloak。

  5. 验证用户名和密码后,Keycloak 将授权码发送给应用程序。

  6. 应用程序将授权码交换为 ID 令牌和访问令牌。应用程序现在可以通过检查 ID 令牌来验证用户的身份。

通过将用户的身份验证委托给 Keycloak,应用程序不必知道如何对用户进行身份验证。当身份验证机制发生变化时,这一点尤其重要。例如,无需更改应用程序即可启用双重验证。这也意味着应用程序无权访问用户的凭据。

与 Keycloak 相关的下一步是前端调用后端。后端 REST API 有一个受保护的端点,只能由具有全局角色 myorn 的用户调用。

为了完全准确,前端被授予代表用户调用后端的权限。这是 OAuth 2.0 美妙之处的一部分。应用程序没有权限做用户能够做的所有事情,只有它应该能够做的事情。

当前端向后端发出请求时,它会在请求中包含访问令牌。默认情况下,Keycloak 使用 JSON Web 签名(JWS)作为令牌格式。这些类型的令牌通常被称为非不透明令牌,这意味着令牌的内容对应用程序直接可见。

令牌还包括一个数字签名,使得验证令牌确实是由 Keycloak 发行的成为可能。本质上,这意味着后端可以验证令牌并读取内容,而无需向 Keycloak 发出请求,从而减少对 Keycloak 服务器的需求,并降低处理后端请求时的延迟。

为了帮助可视化前端向后端发送请求时会发生什么,请查看下图:
在这里插入图片描述

图 2.3:从前端到后端的安全请求简化

图中的步骤如下:

  1. 后端检索 Keycloak 的公钥。后端不需要对后端的所有请求执行此操作,而是可以将密钥缓存在内存中。

  2. 前端向后端发送请求,包括访问令牌。

  3. 后端使用之前检索到的公钥来验证访问令牌是否由受信任的 Keycloak 实例颁发,然后验证令牌是否有效并且令牌包含角色 my 角色。

  4. 后端将结果返回给前端。

您现在对如何使用 Keycloak 保护示例应用程序有了基本的了解。在下一节中,您将学习如何运行示例应用程序。

运行应用程序

在本节中,您将学习如何运行示例应用程序。

如果您的工作站上还没有安装 Node. js,请转到https://nodejs.org/以获取有关如何安装它的说明。

要在 Node.js 上运行前端,请打开终端并运行以下命令:

$ cd Keycloak---Identity-and-Access-Management-for-Modern-Applications-2nd-Edition/ch2/frontend/
$ npm install
$ npm start

接下来,使用以下命令打开一个新终端以运行后端:

$ cd Keycloak---Identity-and-Access-Management-for-Modern-Applications-2nd-Edition/ch2/backend/
$ npm install
$ npm start

现在您已经使用 Node. js 运行了示例应用程序,您可以使用 Keycloak 注册它,我们将在下一节中介绍。

了解如何登录应用程序

在上一章中,介绍了如何开始使用 Keycloak,您学习了如何运行 Keycloak,以及如何创建您的第一个领域。在继续本节之前,您应该让 Keycloak 在创建的领域中运行,如上一章所述。总之,在继续之前,您需要以下内容:

  • Keycloak启动并运行

  • 一个为myrealm的领域

  • 一个为 myrole 的全局角色

  • 具有上述角色的用户

在应用程序可以使用 Keycloak 登录之前,它必须使用 Keycloak 注册为客户端。在注册前端之前,让我们看看如果未注册的应用程序尝试使用 Keycloak 进行身份验证会发生什么。打开http://localhost:8000,然后单击登录按钮。您将看到来自 Keycloak 的错误页面,其中显示未找到客户端消息。此错误告诉您该应用程序未使用 Keycloak 注册。

要使用 Keycloak 注册前端,请打开 Keycloak 管理控制台。在左侧菜单的顶部,有一个选项可以选择您正在使用的领域。确保您选择了名为 mydomain 的领域。在左侧菜单中,单击客户端,然后单击创建客户端。

用以下值填写表单:

  • Client ID:myclient

填写 Client ID 字段后,单击 Next。在以下屏幕上,可以启用和禁用应用程序所需的各种功能。现在,您可以简单地忽略此步骤并单击保存。

在前端应用程序可以使用客户端使用 Keycloak 进行身份验证之前,您必须注册应用程序的 URL。在访问设置下,填写以下值:

  • Valid redirect URIs: http://localhost:8000/
  • Valid post redirect URIs: http://localhost:8000/
  • Web origins: http://localhost:8000

填写表单后,单击保存。在我们继续尝试使用前端应用程序登录之前,让我们进一步了解您输入的最后一个配置值的含义:

  • Valid redirect URIs:当使用客户端应用程序时,此值在 OpenID Connect 授权代码流中非常重要。客户端应用程序无法拥有任何凭据,因为它们对应用程序的最终用户是可见的。为了防止任何恶意应用程序伪装成真正的应用程序,有效的重定向 URI 指示 Keycloak 仅将用户重定向到与有效重定向 URI 匹配的 URL。在这种情况下,由于该值设置为

  • Valid post redirect URIs:用于配置登出请求的重定向 URL,和登录时的重定向 URL 类似。Keycloak 支持设置特殊值 “+” ,表示允许所有有效的重定向 URI 作为登出时的重定向地址。

  • Web origins:此选项为跨域资源共享(CORS)请求注册应用程序的有效 Web 来源。要从 Keycloak 获取令牌,前端应用程序必须向 Keycloak 发送 AJAX 请求,浏览器不允许从一个 Web 来源到另一个 Web 来源的 AJAX 请求,除非使用 CORS。Keycloak 支持添加一个值为 + 的特殊 Web 来源,这导致允许所有有效的重定向 URI 作为 Web 来源。

以下屏幕截图显示了 Keycloak 管理控制台中创建的客户端。
在这里插入图片描述

图 2.4:管理控制台中的客户端设置

现在您可以通过打开http://localhost:8000返回前端。这次,当您单击登录按钮时,您将看到 Keycloak 登录页面。使用您在上一章中创建的用户名和密码登录。

让我们看看 Keycloak 发行的 ID 令牌。单击 Show ID Token 按钮。显示的 ID 令牌如下所示:

{
    "exp": 1664300152,
    "iat": 1664299852,
    "auth_time": 1664298915,
    "jti": "21bb9f32-98ce-49aa-896d-796cb716be59",
    "iss": "http://localhost:8080/realms/myrealm",
    "aud": "myclient",
    "sub": "eb14ea82-45e2-4413-8997-129fd0fc865b",
    "typ": "ID",
    "azp": "myclient",
    "nonce": "ccf5f374-aa07-4280-b63a-efdba9c355c9",
    "session_state": "22884115-55cb-4285-ba92-26c4bf74f74b",
    "at_hash": "ngdMORpXQcEQJ6d9s3uHvw",
    "acr": "0",
    "sid": "22884115-55cb-4285-ba92-26c4bf74f74b",
    "email_verified": true,
    "name": "Stian Thorgersen",
    "preferred_username": "st",
    "given_name": "Stian",
    "family_name": "Thorgersen",
    "email": "st@localdomain.localhost"
}

以下是 ID 令牌中一些更有趣的值的列表:

  • exp:这是自 01/01/197000:00:00 UTC(通常称为 Unix 或 Epoch 时间)以来令牌以秒为单位到期的日期和时间。

  • ISS:这是令牌的发行者,您可能会注意到它是 Keycloak 领域的 URL。这个信息有助于验证令牌的来源可靠性,应用可以通过确认 iss 字段的值是否是信任的 Keycloak 领域 URL,来判断该令牌是否是由合法的 Keycloak 实例颁发的,从而增强认证的安全性。

  • sub:这是经过身份验证的用户的唯一标识符。在整个系统中,无论用户的其他信息(如用户名、姓名等)如何变化,sub 字段始终保持不变,具有稳定性和唯一性。因此在应用开发中,常将 sub 字段作为识别用户的关键标识,用于关联用户的各类数据和权限信息。

  • name:这是经过身份验证的用户的名字和姓氏。用于直观展示用户的姓名信息。在一些需要显示用户真实姓名的场景,如用户个人资料页面、欢迎提示等地方,这个字段提供了直接可用的用户姓名数据。

  • preferred_username:代表认证用户的用户名,但不建议将其作为用户的唯一标识或关键引用。因为用户名具有可变性,用户可能会更改自己的用户名,而且在某些情况下,可能会出现用户名被重新分配给其他用户的情况。相比之下,sub 字段更适合作为用户的唯一标识,在涉及用户身份验证、权限管理和数据关联等操作时,使用 sub 字段能确保数据的准确性和一致性 。

应用程序使用 ID 令牌来建立经过身份验证的用户的身份。

接下来,让我们看看访问令牌。单击显示访问令牌按钮。让我们也看看这个令牌中的一些字段:

  • allowed-origins:这是应用程序允许的 Web 来源列表。后端服务在决定是否应允许 CORS 请求使用 Web 来源时可以使用此字段。

  • realm_access:这包含全局领域角色列表。它是授予用户的角色和客户端有权访问的角色之间的交集。

  • resource_access:包含客户端角色列表,用于确定用户在特定客户端相关资源上的访问权限,与具体客户端的资源访问控制紧密相关。

  • scope:作用有两个,一是决定令牌中包含哪些字段或声明;二是供后端判断该令牌可以访问哪些 API,在控制 API 访问权限方面发挥关键作用。

目前,令牌中的信息是 Keycloak 中可用的默认字段。如果您想添加其他信息,Keycloak 非常灵活,允许您自定义令牌中的内容。

让我们通过为用户添加图片来尝试一下。保持前端打开的选项卡,然后使用 Keycloak 管理控制台打开一个新选项卡。在左侧的菜单中,单击Users,并选择您之前创建的用户。现在让我们为用户添加一个自定义属性。单击Attributes。在表格中,底部将有两个空的输入字段。在关键列中,将值设置为图片,在值列中,将值设置为个人资料图片的 URL(在下面的屏幕截图中,我使用了我的 GitHub 头像)。然后,单击Save。
在这里插入图片描述
在这里插入图片描述
图 2.5:向用户添加自定义属性

现在,回到打开前端的选项卡。要显示个人资料图片,您可以单击刷新按钮。当您单击此按钮时,令牌将被刷新,新的 ID 令牌现在将包含您刚刚添加的图片属性,它允许应用程序为用户显示个人资料图片。

接下来,您将学习如何从前端安全地调用后端。

安全调用后端 REST API

现在,打开http://localhost:3000/并单击公共端点链接。您将看到一条消息说Public message!。公共端点不受 Keycloak 保护,无需访问令牌即可调用。

接下来,让我们尝试受 Keycloak 保护的安全端点。再次打开http://localhost:3000。这一次,单击安全端点链接。现在您将看到一条消息说 Access denied.。此请求不允许,因为它需要有效的访问令牌来调用端点。

现在让我们尝试从前端调用安全端点。打开http://localhost:8000/并单击调用服务。您现在将看到一条消息显示Secret message!。如果相反,您收到消息Access Denied,这很可能是由用户没有 my 角色引起的。

当单击调用服务时,前端会向后端服务发送 AJAX 请求,包括请求中的访问令牌,这允许后端验证调用是否代表具有访问端点所需角色的用户完成。

小结

在本章中,您学习了如何保护您的第一个应用程序,该应用程序由前端 Web 应用程序和带有 Keycloak 的后端 REST API 组成。您还基本了解了 Keycloak 如何利用 OpenID Connect 以标准和安全的方式实现这一切。加上您在本书第一章中学到的知识,您现在已经有了开始学习更多关于 Keycloak 的坚实基础。

在下一章中,我们将深入探讨使用 Keycloak 保护应用程序,让您更好地了解它是如何工作的。

问题

  1. 应用程序如何使用 Keycloak 进行身份验证?

  2. 您需要在 Keycloak 管理控制台中配置什么才能允许应用程序使用 Keycloak 进行身份验证?

  3. 应用程序如何安全地调用受保护的后端服务?


http://www.kler.cn/a/563597.html

相关文章:

  • 深度学习中卷积层(Conv)、BN层(Batch Normalization)和 ReLU层(Rectified Linear Unit)的详细介绍
  • 初识XML
  • Unity XR-XR Interaction Toolkit开发使用方法(七)组件配置(XR Ray Interactor)
  • C++ STL(一)std::vector std::array
  • 玩机日记 15 使用Lucky申请半永久的ssl证书,并且替换阿里云的自签名证书
  • 集合与反射
  • 算法平台的开源框架
  • PDF处理控件Aspose.PDF教程:使用 Python 将 PDF 转换为 TIFF
  • 网页五子棋——项目测试
  • HarmonyOS Design 介绍
  • 基于ffmpeg+openGL ES实现的视频编辑工具-添加背景音乐(十)
  • vue+element-dialog:修改关闭icon / 遮罩层不能挡住弹窗 / 遮罩层不能遮挡元素
  • miqiu的分布式(三):JVM本地锁失效的三大典型场景
  • Java集合设计模式面试题
  • 5 分钟用满血 DeepSeek R1 搭建个人 AI 知识库(含本地部署)
  • 十一、大数据治理平台总体功能架构
  • leetcode 541. 反转字符串 II 简单
  • Document对象
  • docker 安装 seafile 企业云盘
  • flask 是如何分发请求的?