介绍
使用Keycloak作为第三方认证服务,Kong作为API网关与Keycloak进行对接,打通两者用户数据库,并使用Kong当中的ACL插件进行接口权限的设计。主要涉及到如下框架:
- Kong——开源API网关
- Keycloak——一个OpenID认证服务
- Konga——API网关后台管理可视化界面

下文将记录Kong、Konga和Keycloak三者的安装和对接过程,并介绍权限打通的设计思路。以下是主要步骤:
- 创建Dockerfile,创建带有kong-oidc插件的镜像
- 构建上述镜像
- 创建
docker-compose.yml
文件,配置Kong,Konga和Keycloak的相关信息 - 启动kong-db服务
- 运行
migrations
- 启动Kong服务
- 验证kong-oidc插件是否可用
- 使用StreamSet打通Keycloak和Kong用户数据库,进行数据同步
- 添加kong-oidc插件和ACL插件
- 测试认证是否可行
安装过程
创建Dockerfile文件
第一,我们需要创建有关于Kong的镜像。我们还需要在这个镜像的基础上安装kong-oidc插件。我们可以采用以下两种方法进行:
- 修改现有的、正在运行的容器并提交更改
- 创建Dockerfile文件,并镜像构建
我们将采用第二种方法,以下是Dockerfile文件
1 | mkdir -p docker/kong |
使用vim创建并打开文件,写入以下内容:
1 | FROM kong:1.4.2-centos |
以上代码将会将安装kong1.4.2版本,以及在此基础上安装kong-oidc插件,接下来构建该文件:
1 | docker build -t kong:1.4.2-centos-oidc docker/kong/ |
如果遇到Warning: The directory '/root/.cache/luarocks' or its parent directory is not owned by the current user
就忽略。
安装及配置Kong
接下来创建docker-compose.yml
文件
1 | touch docker-compose.yml |
打开这个文件,并进行如下配置
1 | version: '3.4' |
接下来,采用下面的命令启动kong-db服务,其中-d
是告诉docker在后台运行Docker Compose进程
1 | docker-compose up -d kong-db |
验证服务是否已经启动
1 | docker-compose ps |
接下来将迁移kong-db数据库,采用migrations
命令。下面这个命令将驱动一个kong服务,-rm
表示该服务将在命令运行之后关闭。
1 | docker-compose run --rm kong kong migrations up |
最后,我们将Kong启动,并且检查其运行状态
1 | docker-compose up -d kong |
检查Kong的管理API,检查OIDC插件是否可以在服务器上使用
1 | curl -s http://localhost:8001 | jq .plugins.available_on_server.oidc |
将返回true
。但是,虽然OIDC插件在Kong上可用,但是还没有配置Keycloak,实际上还不能进行API的保护。
至此为止,就完成了Kong的安装
安装Konga可视化终端
Konga是开源的Kong可视化界面,方面API网关管理人员对Kong进行可视化管理,安装方法和Kong类似。
配置docker-compose.yml
文件,添加如下内容:
1 | konga-prepare: |
首先将konga的postgresql数据启动:
1 | docker-compose up -d konga-prepare |
检查是否启动成功:
1 | docker-compose ps |
接下来在docker-compose.yml
再配置Konga镜像:
1 | konga: |
再次启动konga
1 | docker-compose up -d konga |
检查是否启动成功:
1 | docker-compose ps |
用浏览器访问“IP地址:1337”端口,注册后台管理用户名密码,检查是否能够正常访问,进入后台管理界面后,配置和Kong的对接:
对接完成后,可以用Konga查看并配置Kong网关的信息了。
安装Keycloak
本节欸将重点配置Keycloak的安装。我们还是采用docker对Keycloak进行安装。

在本节中,我们将运行以下步骤:
- 修改
docker-compose.yml
来添加Keycloak和它的可视化终端服务 - 注册Keycloak数据库服务
- 注册Keycloak服务
- 登录Keycloak
- 为Kong添加Keycloak终端
- 添加新用户
使用Docker安装Keycloak
重新打开docker-compose.yml
.为Keycloak添加网络:
1 | networks: |
接下来将Keycloak数据库添加到docker-compose.yml
中:
1 | services: |
启动服务
1 | docker-compose up -d keycloak-db |
验证是否可以使用(确保它的状态是启动的)
1 | docker-compose ps |
下一步,将Keycloak添加到docker-compose.yml
的services中:
1 | services: |
最后启动Keycloak服务:
1 | docker-compose up -d keycloak |
验证服务是否可用
1 | docker-compose ps |
添加客户端到Keycloak中
点击Administration Console进入到控制台当中,此时需要输入用户名和密码:
在Master
域下,创建客户端:

在添加客户端页面,填写“客户端ID”为kong,点击保存按钮。

在详情页面中,可以看到“Access Type”,我们需要选择的是“Confidential”,其中“Root URL”是“IP地址:8000”(Kong所接管的端口),以及“Valid Redirect URIs”填写“/*”就可以了,我们的设置如下:

点击保存之后,在“Credentials”页面中会有对应的“Secret”,这个密钥是需要在Kong当中进行配置的

为Keycloak添加用户
要添加用户,单击左侧侧边栏的“Users”选项卡,然后单击右侧的“add user”按钮

在下一页,将“Username”设置为“用户”,并将“Email Enable”开关设置为“On”。然后,点击“Save”按钮。
点击“Credentials”选项卡,输入密码,确认,确保“Temporary”开关设置为“关闭”。然后,点击“Save”按钮。
至此,在Keycloak当中的配置已经完成了。
将Kong和Keycloak进行对接
接下来将配置Keycloak和Kong的对接部分
创建服务和路由(此处省略)
在全局范围内安装oidc插件
点击左侧“Plugin”后,再点击“ADD GLOBAL PLUGINS”,在Other当中,又OIDC插件,找到并点击“ADD PLUGIN”,会弹出如下表单,表单当中的条目信息可以参考:https://github.com/nokia/kong-oidc在GitHub上的首页。
其中以下几个需要重点关注:
- client_id:需要和Keycloak中创建的client_id对应一致
- client_secret:需要需要和Keycloak中自动生成的secret一致
- realm:默认就是Keycloak中的master域
- redirect after logout uri:/
- discovery:根据OIDC填写:http://XXXXXX:8180/auth/realms/master/.well-known/openid-configuration
配置完成后,访问Kong接管的API接口,会自动跳转到Keycloak的登录界面,说明Keycloak和Kong对接完成
存在问题
官方给出了以上配置虽然打通了Kong和Keycloak,但是由于登录是Keycloak进行管理,采用的是Keycloak中的用户,而这些用户和Kong当中的“Consumer”是分离的,而且此时不能够通过Keycloak进行用户权限的管理。
如果将用户管理交给Keycloak,就会架空Kong当中的Consumer,最好是有办法将Kong中的Consumer和Keycloak中的User打通
目标
- 打通Keycloak和Kong中的用户表
- 能够使得ACL插件进行白名单和黑名单的访问控制
方法
- 使用ETL工具两者数据表,将ID和用户名进行同步
- 修改ACL插件使其能够获取到认证过后的
authenticated_consumer
操作步骤
ETL工具同步
此处过程省略
修改ACL插件
在kong-oidc插件官方文档中,给出了X-Userinfo
是被注入在请求头当中的,例如:
1 | X-Userinfo: {"preferred_username":"alice","id":"60f65308-3510-40ca-83f0-e9c0151cc680","sub":"60f65308-3510-40ca-83f0-e9c0151cc680"} |
而该插件同样在ngx.ctx.authenticated_consumer
中设置了变量,他能够支持其他插件对认证通过用户进行操作,因此,可以让ACL获取该信息,利用该信息和现有“Consumer”做匹配。
1 | ngx.ctx.authenticated_credential = { |
修改如下:
进入docker容器当中
1
sudo docker exec -it 容器ID /bin/bash
进入Kong插件所在目录
1
cd /usr/local/share/lua/5.1/kong/plugins/acl
打开group.lua文件,对
get_current_consumer_id
做修改1
2
3
4
5local function get_current_consumer_id()
kong.log.err("oidc info:", ngx.ctx.authenticated_credential.id)
return (kong.client.get_consumer() or EMPTY).id or
(kong.client.get_credential() or EMPTY).consumer_id or
+ (ngx.ctx.authenticated_credential or EMPTY).id
这样就可以做到Kong和Keycloak真正打通。