目录
[6.1 Keycloak配置](#6.1 Keycloak配置)
[6.2 Jenkins配置](#6.2 Jenkins配置)
[7.1 Keycloak配置](#7.1 Keycloak配置)
[7.2 Gitlab配置](#7.2 Gitlab配置)
[8.1 Keycloak配置](#8.1 Keycloak配置)
[8.2 Kibana配置](#8.2 Kibana配置)
[9.1 Keycloak配置](#9.1 Keycloak配置)
[9.2 Grafana配置](#9.2 Grafana配置)
[10.1 单点登录](#10.1 单点登录)
[10.2 权限控制](#10.2 权限控制)
[10.3 用户自助平台](#10.3 用户自助平台)
在开源身份认证与访问管理平台 - Keycloak(一)中我们做好了前期的准备工作,包括创建服务、与AD集成。接下来演示跟各个系统的集成步骤。
六、Jenkins集成
6.1 Keycloak配置
在Clients中创建jenkins的client,主要的参数配置如图,其中各个URL的域名换成实际的域名:



添加groups mapper,确保用户会携带group信息传递给Jenkins侧:


创建Credentials并复制Secret,用来给jenkins侧配置使用:

6.2 Jenkins配置
由于Keycloak的HTTPS域名使用了自签名证书,我们需要让Jenkins信任证书,这里直接重写entrypoint脚本:
bash
# jenkins-entrypoint.sh脚本内容
#!/bin/bash
set -e
# 导入 Root CA 证书
if [ -f /tmp/rootCA.pem ]; then
echo "Importing Root CA certificate..."
keytool -import \
-alias my-root-ca \
-keystore $JAVA_HOME/lib/security/cacerts \
-file /tmp/rootCA.pem \
-storepass changeit \
-noprompt \
-trustcacerts 2>/dev/null && echo "Certificate imported." \
|| echo "Certificate already exists, skipping."
fi
# 交还给官方原始 entrypoint(保持官方行为完全不变)
exec su -s /bin/bash jenkins -c "/usr/bin/tini -- /usr/local/bin/jenkins.sh $*"
更换Jenkins的启动脚本:
bash
# docker-compose.yml
services:
jenkins:
image: jenkins/jenkins:2.556
container_name: jenkins
user: root
# 这里指定自定义的脚本
entrypoint: /var/entrypoint/jenkins-entrypoint.sh
restart: always
ports:
- "8088:8080"
environment:
- JAVA_OPTS=-Djenkins.install.runSetupWizard=false -Dhudson.security.SecurityRealm.allowLocalLogin=true
volumes:
- ./jenkins_home:/var/jenkins_home
- ./certs/rootCA.pem:/tmp/rootCA.pem:ro
- ./jenkins-entrypoint.sh:/var/entrypoint/jenkins-entrypoint.sh:ro
networks:
- jenkins_net
networks:
jenkins_net:
重启Jenkins后我们可以在控制台直接配置,确定相关插件已经安装:


在全局配置的安全域中改为使用Openid连接,并填写相关信息:


按照上面填写并保存,这样user和group等信息就能传递到Jenkins中。
生产环境的RBAC最佳实践是直接对group授权:


以上的效果是:dev组中用户登录进来后,只有DEV和UAT环境的Job执行权限;infra组中的用户登录进来后,是管理员权限。
七、Gitlab集成
7.1 Keycloak配置
创建Client,步骤相似,只是URL不同:


同样创建Credentials以及groups mapper,这里不再截图。
7.2 Gitlab配置
把Keycloak的root ca证书放到config/trusted-certs/目录下。
更改gitlab.rb配置文件,增加如下内容:
bash
# gitlab.rb片段
gitlab_rails['omniauth_enabled'] = true
gitlab_rails['omniauth_allow_single_sign_on'] = ['openid_connect']
gitlab_rails['omniauth_block_auto_created_users'] = false
gitlab_rails['omniauth_auto_sign_in_with_provider'] = 'openid_connect'
gitlab_rails['password_authentication_enabled_for_web'] = true
gitlab_rails['omniauth_providers'] = [
{
name: "openid_connect",
label: "Keycloak",
args: {
name: "openid_connect",
scope: ["openid","profile","email"],
response_type: "code",
issuer: "https://keycloak.tools.devops.com/realms/tools-devops",
discovery: true,
client_auth_method: "query",
uid_field: "preferred_username",
client_options: {
identifier: "gitlab",
secret: "G5xWm12OkerUASDGHIf024NRy9OlZdfrb",
redirect_uri: "https://gitlab.tools.devops.com/users/auth/openid_connect/callback"
}
}
}
]
开源版本Gitlab配置到这里就可以重启服务了,后续各个代码仓库的管理员手动给用户授权。
要实现比较精细的权限控制,需要Premium版本或者创建脚本实现,这里跳过。
八、Kibana集成
8.1 Keycloak配置
主要配置如下:

8.2 Kibana配置
开源版本Kibana依赖oauth2-proxy服务做代理:
bash
# oidc.yaml配置
apiVersion: v1
kind: Secret
metadata:
name: oauth2-proxy-secret
namespace: log
type: Opaque
stringData:
client-id: kibana
client-secret: "z6QXICS29DDdFmEjVD8d9qUS5rNcGzd8"
cookie-secret: "0ea1a614d7b2cde955f3f4b8ae2b812e"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: oauth2-proxy
namespace: log
spec:
replicas: 1
selector:
matchLabels:
app: oauth2-proxy
template:
metadata:
labels:
app: oauth2-proxy
spec:
nodeSelector:
name: iwt-oke-1-node-pool-2
containers:
- name: oauth2-proxy
image: quay.io/oauth2-proxy/oauth2-proxy:v7.6.0
args:
- --provider=oidc
- --oidc-issuer-url=https://keycloak.tools.devops.com/realms/tools-devops
- --client-id=$(CLIENT_ID)
- --client-secret=$(CLIENT_SECRET)
- --cookie-secret=$(COOKIE_SECRET)
- --cookie-secure=true
- --cookie-samesite=lax
- --cookie-domain=kibana.iwt.devops.com
- --cookie-path=/
- --email-domain=*
- --upstream=http://iwt-ctx-elk-kibana.log.svc.cluster.local:5601
- --http-address=0.0.0.0:4180
- --redirect-url=https://kibana.iwt.devops.com/oauth2/callback
- --set-authorization-header=true
- --pass-access-token=true
- --pass-user-headers=true
- --skip-provider-button=true
env:
- name: CLIENT_ID
valueFrom:
secretKeyRef:
name: oauth2-proxy-secret
key: client-id
- name: CLIENT_SECRET
valueFrom:
secretKeyRef:
name: oauth2-proxy-secret
key: client-secret
- name: COOKIE_SECRET
valueFrom:
secretKeyRef:
name: oauth2-proxy-secret
key: cookie-secret
- name: OAUTH2_PROXY_TLS_CLIENT_CA_FILE
value: /etc/ssl/certs/keycloak/keycloak-ca.crt
volumeMounts:
- name: keycloak-ca
mountPath: /etc/ssl/certs/keycloak-ca.crt
subPath: cert.crt
volumes:
- name: keycloak-ca
configMap:
name: keycloak-ca
---
apiVersion: v1
kind: Service
metadata:
name: oauth2-proxy
namespace: log
spec:
ports:
- port: 80
targetPort: 4180
selector:
app: oauth2-proxy
---
apiVersion: v1
data:
cert.crt: |
-----BEGIN CERTIFICATE-----
[此处省略]
-----END CERTIFICATE-----
kind: ConfigMap
metadata:
name: keycloak-ca
namespace: log
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: private-tools-ingress
namespace: log
annotations:
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-connect-timeout: "75"
nginx.ingress.kubernetes.io/proxy-buffering: "off"
spec:
ingressClassName: nginx
rules:
- host: kibana.iwt.devops.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: oauth2-proxy
port:
number: 80
- host: kibana-admin.iwt.devops.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: iwt-ctx-elk-kibana-admin
port:
number: 5601
Kibana配置文件开启anonymous模式:
bash
# kibana.yml配置片段
server.name: iwt-ctx-elk-kibana
server.host: "0.0.0.0"
i18n.locale: "en"
elasticsearch.hosts: [ "http://iwt-ctx-elk-es:9200" ]
elasticsearch.username: "kibana_system"
elasticsearch.password: "密码"
server.publicBaseUrl: "https://kibana.iwt.devops.com"
xpack.encryptedSavedObjects.encryptionKey: "此处省略"
xpack.security.encryptionKey: "此处省略"
xpack.reporting.encryptionKey: "此处省略"
xpack.security.authc.providers:
#basic.basic1:
#order: 1
anonymous.anonymous1:
order: 0
credentials:
username: "kibana_user"
password: "password"
注意:这里iwt-ctx-elk-kibana-admin是给管理员使用的。
九、Grafana集成
9.1 Keycloak配置
主要配置如下:

9.2 Grafana配置
首先修改配置文件:
bash
# grafana.ini配置片段,增加如下内容
[server]
root_url = https://grafana.prd.devops.com/
[auth]
disable_login_form = false
oauth_auto_login = true
[auth.basic]
enabled = true
[auth.generic_oauth]
enabled = true
name = Keycloak
allow_sign_up = true
client_id = grafana
client_secret = iHRHYfOfnWyI1inP5Ov59ZE2KXlPzvuh
scopes = openid profile email
auth_url = https://keycloak.tools.devops.com/realms/tools-devops/protocol/openid-connect/auth
token_url = https://keycloak.tools.devops.com/realms/tools-devops/protocol/openid-connect/token
api_url = https://keycloak.tools.devops.com/realms/tools-devops/protocol/openid-connect/userinfo
#这里控制infra组是Admin权限,其他组是Viewer权限
role_attribute_path = contains(groups[*], 'infra') && 'Admin' || 'Viewer'
Keycloak自签名证书的信任,通过SSL_CERT_FILE参数可以实现,这里省略。
十、验证
10.1 单点登录
我们首次登录任一个系统,如Gitlab,浏览器自动跳转到了Keycloak登录页:

登录zhangsan或者lisi的账号,浏览器跳转回Gitlab并登录成功:

这时我们访问其他集成过的系统,发现直接静默登录:



以上效果表示我们的配置已经生效。
10.2 权限控制
由于Kibana和Gitlab都是开源免费版,没有继续做精细的RBAC权限控制,所以我们只用Grafana和Jenkins为例验证效果:
- zhangsan登录Grafana和Jenkins后,如10.1中所示,在两个系统中都是管理员权限;
- lisi登陆后,我们查看权限,发现是普通权限,跟预期相符;


10.3 用户自助平台
上面我们切换用户的时候,需要关闭并重新打开浏览器,比较麻烦。Keycloak给普通用户提供了Keycloak Account Console,用户登陆后可以:
- 修改个人信息和密码
- 绑定手机/邮箱验证器(MFA)
- 查看并点击跳转业务系统
- 一键踢掉其他设备的登录状态
例如本示例中的https://keycloak.tools.devops.com/realms/tools-devops/account


