如何将 Keycloak 集成到 Apache APISIX 中以进行身份验证

2021 年 12 月 21 日,作者:Xinxin Zhu & Yilin Zeng

本文将详细介绍如何通过 OpenID-Connect 协议和 Keycloak 在 Apache APISIX 中进行身份验证。

Keycloak 是一个面向现代应用程序和服务的开源身份和访问管理解决方案。Keycloak 支持单点登录 (Single-Sign On),使服务能够通过 OpenID Connect、OAuth 2.0 等协议与 Keycloak 交互。Keycloak 还支持与不同的身份验证服务集成,例如 Github、Google 和 Facebook。

此外,Keycloak 还支持用户联合身份验证,并且可以通过 LDAP 和 Kerberos 导入用户。有关 Keycloak 的更多信息,请参阅官方文档

Apache APISIX 是一个动态、实时、高性能的 API 网关,提供丰富的流量管理功能。该项目提供负载均衡、动态上游、金丝雀发布、熔断、身份验证、可观察性以及许多有用的插件。此外,该网关支持动态插件更改以及热更新。Apache APISIX 的 OpenID Connect 插件允许用户使用集中的身份验证模式通过 OpenID Connect 替换传统的身份验证模式。

如何使用

安装 Apache APISIX

安装依赖项

Apache APISIX 运行时环境需要依赖于 NGINX 和 etcd。

在安装 Apache APISIX 之前,请根据您使用的操作系统安装依赖项。我们提供了 CentOS7、Fedora 31 和 32、Ubuntu 16.04 和 18.04、Debian 9 和 10 以及 macOS 的依赖项安装说明。请参阅安装依赖项以获取更多详细信息。

通过 RPM 包安装 (CentOS 7)

此安装方法适用于 CentOS 7;请运行以下命令安装 Apache APISIX。

sudo yum install -y https://github.com/apache/apisix/releases/download/2.7/apisix-2.7-0.x86_64.rpm

通过 Docker 安装

通过 Helm Chart 安装

初始化依赖项

运行以下命令以初始化 NGINX 配置文件和 etcd。

make init

启动 Apache APISIX

运行以下命令以启动 Apache APISIX。

apisix start

启动 Keycloak

这里我们使用 docker 启动 Keycloak。

docker run -p 8080:8080 -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=password -e DB_VENDOR=h2  -d jboss/keycloak:9.0.2

执行后,您需要验证 Keycloak 是否已成功启动。

docker ps

配置 Keycloak

Keycloak 启动后,使用浏览器访问 "http://127.0.0.1:8080/auth/admin/",并输入 admin/password 帐户密码以登录到管理员控制台。

创建一个 realm

首先,您需要创建一个名为 apisix_test_realm 的 realm。在 Keycloak 中,realm 是一个专门用于管理项目的工作区,不同 realm 的资源彼此隔离。

Keycloak 中的 realm 分为两类:一类是 master realm,它在 Keycloak 首次启动时创建,用于管理管理员帐户和创建其他 realm。第二类是由管理员在 master realm 中创建的 其他 realm,可用于在此 realm 中创建、管理和使用用户和应用程序。第二类是由管理员在 master realm 中创建的其他 realm,用户和应用程序可以在其中创建、管理和使用。有关更多详细信息,请参阅 Keycloak 中的 realm 和用户部分

Create realm
Edit realm title

创建一个客户端

下一步是创建 OpenID Connect Client。在 Keycloak 中,客户端是指允许向 Keycloak 发起身份验证的客户端。

在本示例场景中,Apache APISIX 相当于一个客户端,负责向 Keycloak 发起身份验证请求,因此我们创建一个名为 apisix 的客户端。有关客户端的更多详细信息,请参阅 Keycloak OIDC 客户端

Create OpenID Client
Create Client title

配置客户端

创建客户端后,您需要为客户端配置 Apache APISIX 访问类型。

在 Keycloak 中,有三种访问类型

  1. Confidential(保密):用于需要执行浏览器登录的应用程序,客户端将通过 client secret 获取 access token,主要用于服务器渲染的 Web 系统。

  2. Public(公开):用于需要执行浏览器登录的应用程序,主要用于使用 vue 和 react 实现的前端项目。

  3. Bearer-only(仅 Bearer):用于不需要执行浏览器登录的应用程序,仅允许使用 bearer token 访问,主要用于 RESTful API 场景。

有关客户端设置的更多详细信息,请参阅 Keycloak OIDC 客户端高级设置

由于我们使用 Apache APISIX 作为服务器端的客户端,我们可以选择 "Confidential" 访问类型或 "Bearer-only" 访问类型。在下面的演示中,我们以 "Confidential" 访问类型为例。

Set Client type

创建用户

Keycloak 支持与其他第三方用户系统(如 Google 和 Facebook)对接,或使用 LDAP 导入或手动创建用户。在这里,我们将使用“手动创建用户”进行演示。

Create user
Add user info

然后在“Credentials(凭据)”页面中设置用户的密码。

Set user password

创建路由

配置 Keycloak 后,您需要创建一个路由并启用 Openid-Connect 插件。有关此插件配置的详细信息,请参阅 Apache APISIX OpenID-Connect 插件

获取 client_id 和 client_secret

Get client information

在以上配置中。

  • client_id 是之前创建客户端时使用的名称,即 apisix

  • client_secret 应从 Clients-apisix-Credentials 中获取,例如:d5c42c50-3e71-4bbbe-aa9e-31083ab29da4

获取发现配置

Get configuration

转到“Realm Settings-General-Endpoints(Realm 设置-常规-端点)”,选择 OpenID Endpoint Configuration 链接并复制该链接指向的地址,例如:`http://127.0.0.1:8080/auth/realms/apisix_test_realm/.well-known/openid-configuration`。

创建路由并启用插件

使用以下命令访问 Apache APISIX Admin 界面以创建路由,将上游设置为 httpbin.org,并启用 OpenID Connect 插件进行身份验证。

注意:如果在创建客户端时选择 bearer-only 作为访问类型,则需要在配置路由时将 bearer_only 设置为 true,以便访问 Apache APISIX 时不会跳转到 Keycloak 登录屏幕。

curl  -XPOST 127.0.0.1:9080/apisix/admin/routes -H "X-Api-Key: edd1c9f034335f136f87ad84b625c8f1" -d '{
    "uri":"/*",
    "plugins":{
        "openid-connect":{
            "client_id":"apisix",
            "client_secret":"d5c42c50-3e71-4bbe-aa9e-31083ab29da4",
            "discovery":"http://127.0.0.1:8080/auth/realms/apisix_test_realm/.well-known/openid-configuration",
            "scope":"openid profile",
            "bearer_only":false,
            "realm":"apisix_test_realm",
            "introspection_endpoint_auth_method":"client_secret_post",
            "redirect_uri":"http://127.0.0.1:9080/"
        }
    },
    "upstream":{
        "type":"roundrobin",
        "nodes":{
            "httpbin.org:80":1
        }
    }
}'

访问测试

完成以上配置后,我们准备在 Apache APISIX 中执行相关的访问测试。

访问 Apache APISIX

使用浏览器访问 http://127.0.0.1:9080/image/png

由于已启用 OpenID-Connect 插件,并且 bearer-only 设置为 false,因此当您首次访问此路径时,Apache APISIX 将重定向到 Keycloak 中 apisix_test_realm 配置的登录屏幕,并发出用户登录请求。

Login page

输入在 Keycloak 配置期间创建的用户 peter 以完成用户登录。

成功访问

成功登录后,浏览器将再次将链接重定向到 http://127.0.0.1:9080/image/png,并将成功访问图像内容。该内容与上游 http://httpbin.org/image/png 的内容相同。

Access successfully

注销

测试后,使用浏览器访问 http:/127.0.0.1:9080/logout 以注销您的帐户。

注意:注销路径可以通过 OpenID-Connect 插件配置中的 logout_path 指定,默认为 logout

总结

本文介绍了在 Apache APISIX 中使用 OpenID-Connect 协议和 Keycloak 进行身份验证的过程。通过与 Keycloak 集成,Apache APISIX 可以配置为对用户和应用程序服务进行身份验证和授权,从而大大减少了相关的开发工作。

有关 Apache APISIX 中身份验证实现的更多信息,请参阅 Apache APISIX 博客