Skip to main content

如何在 Apache APISIX 中集成 Keycloak 实现身份认证

· 阅读需约 8 分钟
朱欣欣
苏钰

本文通过详细的步骤为大家展示了如何在 Apache APISIX 使用 OpenID-Connect 协议和 Keycloak 进行身份认证。通过对接 Keycloak,Apache APISIX 仅需通过配置即可实现对使用者和应用服务进行认证与鉴权,从而大大减少了相关开发工作。

Keycloak-APISIX 集成
Click to Preview

什么是 Keycloak

Keycloak 是一个针对现代应用程序和服务的开源身份和访问管理解决方案。Keycloak 支持单点登录(Single-Sign On),因此服务可以通过 OpenID Connect、OAuth 2.0 等协议对接 Keycloak。同时 Keycloak 也支持集成不同的身份认证服务,例如 Github、Google 和 Facebook 等。

另外 Keycloak 也支持用户联邦功能,可以通过 LDAP 或 Kerberos 来导入用户。更多 Keycloak 内容可以参考官方文档介绍

如何使用

环境准备

在进行如下步骤前,请确保环境中已启动 Apache APISIX。

启动 Keycloak

这里我们使用 docker-compose 将 Keycloak 与其所依赖的的 PostgreSQL 一并启动。

version: '3.7'

services:
postgres:
image: postgres:12.2
container_name: postgres
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: password

keycloak:
image: jboss/keycloak:9.0.2
container_name: keycloak
environment:
DB_VENDOR: POSTGRES
DB_ADDR: postgres
DB_DATABASE: keycloak
DB_USER: keycloak
DB_PASSWORD: password
KEYCLOAK_USER: admin
KEYCLOAK_PASSWORD: password
PROXY_ADDRESS_FORWARDING: "true"
ports:
- 8080:8080
depends_on:
- postgres
docker-compose up

执行完毕后需要确认 Keycloak 和 PostgreSQL 是否已成功启动。

docker-compose ps

配置 Keycloak

Keycloak 启动完成之后,使用浏览器访问 "http://127.0.0.1:8080/auth/admin/",并键入 admin/password 账号密码进行登录管理员控制台。

创建 realm

首先,创建一个名称为 apisix_test_realmrealm。在 Keycloak 中,realm 是一个专门用来管理项目的工作区,不同 realm之间的资源是相互隔离的。

Keycloak 中 realm 分为两类:一类是 master realm,由 Keycloak 刚启动时创建,用于管理 admin 账号以及创建其他的 realm。第二类是 other realm,由 master realm 中的 admin 创建,可以在该 realm 中进行用户和应用的创建并进行管理和使用。更多细节可参考 Keycloak 中 realm 和 users 相关内容。

创建 realm
Click to Preview

编辑 realm 名称
Click to Preview

创建 Client

接下来需要创建 OpenID Connect Client。在 Keycloak 中,Client 表示允许向 Keycloak 发起身份认证的客户端。

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

创建 OpenID Client
Click to Preview

创建 Client 名称
Click to Preview

配置 Client

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

在 Keycloak 中 Access Type 分为三类:

  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, 因此可以选择类型一或类型三(这里以类型一为例进行演示)。

配置 Client 类型
Click to Preview

创建 User

Keycloak 支持对接其他第三方的用户系统,例如 Google 和 Facebook。或者使用 LDAP 的方式进行导入或手动创建用户,这里我们使用「手动创建用户」来进行演示。

创建用户
Click to Preview

添加用户相关信息
Click to Preview

在 Credentials 页面设置用户的密码。

设置用户密码
Click to Preview

创建路由

Keycloak 配置完成后,需要在 Apache APISIX 中创建路由并开启 Openid-Connect 插件,具体关于该插件的配置文档可以参考 Apache APISIX OpenID-Connect 插件

获取 client_id 和 client_secret

获取 Client 相关信息
Click to Preview

上图配置中:

  • client_id 为之前创建 Client 时使用的名称,即 apisix
  • client_secret 则需要进入 Clients-apisix-Credentials 中获取,例如:d5c42c50-3e71-4bbe-aa9e-31083ab29da4

获取 discovery 配置项

获取配置
Click to Preview

进入 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 作为 Access Type,在配置路由是需要将 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-onlyfalse 。因此第一次访问该路径时, Apache APISIX 将重定向到 Keycloak 中 apisix_test_realm 中配置的登录界面,进行用户登录请求。

登录页面
Click to Preview

输入之前配置 Keycloak 时创建的 User peter,即可完成用户登录。

访问成功

登录成功后,浏览器又会将链接重定向到 "http://127.0.0.1:9080/image/png"。并成功访问到该图片内容,该内容与上游 "http://httpbin.org/image/png" 一致。

访问成功
Click to Preview

登出账号

测试完毕后,使用浏览器访问 "http:/127.0.0.1:9080/logout" 进行账号登出。

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

总结

本文通过详细的步骤为大家展示了如何在 Apache APISIX 使用 OpenID-Connect 协议和 Keycloak 进行身份认证。通过对接 Keycloak,Apache APISIX 仅需通过配置即可实现对使用者和应用服务进行认证与鉴权,从而大大减少了相关开发工作。

更多关于 Apache APISIX 中的身份认证功能实现也可参考文章《使用 Apache APISIX 和 Okta 来实现集中式身份认证》