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

2021 年 12 月 21 日 by 朱欣欣 & 曾一琳

本文将通过详细步骤展示如何使用 OpenID-Connect 协议和 Keycloak 在 Apache APISIX 中实现身份验证。

Keycloak 是一款为现代应用程序和服务提供的开源身份验证和访问管理解决方案。 Keycloak 支持单点登录(SSO),使服务能够通过 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。 另一类是 其他 realm,由 master realm 中的管理员创建,可以用来在这个 realm 中创建、管理和使用用户和应用程序。 有关更多详细信息,请参考 Keycloak 中的 realm 和用户部分

Create realm
Edit realm title

创建 Client

下一步是创建 OpenID Connect Client。 在 Keycloak 中,Client 表示允许启动 Keycloak 身份验证的客户端。

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

Create OpenID Client
Create Client title

配置 Client

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

在 Keycloak 中,访问类型有三种:

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

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

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

有关 Client 设置的更多详细信息,请参考 Keycloak OIDC Clients 高级设置

由于我们在服务器端使用 Apache APISIX 作为 Client,我们可以选择 "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 是之前创建 Client 时使用的名称,即 apisix

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

获取发现配置

Get configuration

转到 Realm Settings-General-Endpoints,选择 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 插件进行身份验证。

注意:如果您在创建 Client 时选择 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 博客