目录
[2.1 Realm](#2.1 Realm)
[2.2 Client](#2.2 Client)
[2.3 User与Group](#2.3 User与Group)
[2.4 Role](#2.4 Role)
[2.5 Identity Provider](#2.5 Identity Provider)
[2.6 Token](#2.6 Token)
[3.1 认证流程](#3.1 认证流程)
[4.1 部署Keycloak](#4.1 部署Keycloak)
[4.2 反向代理(HTTPS)](#4.2 反向代理(HTTPS))
[4.3 管理员Web UI](#4.3 管理员Web UI)
[五、Active Directory(AD)集成](#五、Active Directory(AD)集成)
[5.1 准备AD测试用户和组](#5.1 准备AD测试用户和组)
[5.2 Keycloak配置LDAP用户联邦](#5.2 Keycloak配置LDAP用户联邦)
[5.3 LDAP属性映射](#5.3 LDAP属性映射)
一、简介
Keycloak是由Red Hat开源的企业级身份认证与访问管理(IAM)平台,基于OAuth 2.0、OpenID Connect(OIDC)和SAML 2.0协议,为应用提供统一的单点登录(SSO)解决方案。
无论是内部研发工具(GitLab、Jenkins、Harbor、ArgoCD等),还是面向用户的Web应用,Keycloak都能作为统一的认证网关,实现"一处登录、全站通行"的效果。
核心能力一览:
| 能力 | 说明 |
|---|---|
| 单点登录 (SSO) | 一次认证,访问多个系统 |
| 多协议支持 | OAuth 2.0 / OIDC / SAML 2.0 |
| 多因素认证 (MFA) | TOTP / WebAuthn / 短信验证码 |
| 用户联邦 | 对接 LDAP / Active Directory |
| 细粒度授权 | Role-Based / Attribute-Based 权限控制 |
| Admin Console | 可视化管理界面 |
二、核心概念
在深入实战之前,先理解Keycloak的几个关键概念:
2.1 Realm
Realm是Keycloak的最顶层隔离单元,相当于一个独立的租户空间。每个Realm有自己的用户、客户端、角色和配置,互相隔离互不影响。
masterRealm:管理员专用,用于管理其他Realm- 业务Realm:例如tools-devops,承载你的所有业务系统
2.2 Client
Client代表需要接入Keycloa 的应用系统,例如GitLab、Jenkins都可以是Client。每个Client 有自己的Client ID、Secret和回调地址配置。
2.3 User与Group
用户可以在Keycloak本地创建,也可以通过用户联邦从LDAP/AD同步。
Group用于批量管理用户权限。
2.4 Role
主要了解Role有两种类型:
- Realm Role:全局角色,跨Client有效
- Client Role:特定Client下的角色
2.5 Identity Provider
允许Keycloak作为代理,接入外部IdP(如企业 LDAP、SAML IdP),实现身份联邦。
2.6 Token
Keycloak颁发三种JWT Token给接入的Client:
ID Token: 包含用户身份信息,用于前端解析Access Token: 访问资源服务器,短效(默认 5 分钟)Refresh Token: 刷新 Access Token,长效(默认 30 分钟)
三、Keycloak架构

3.1 认证流程
用户第一次访问的认证流程:
假设访问的是Gitlab,如架构图所示,会经过完整的①②③④⑤⑥⑦⑧流程,其中除了③用户提交账号密码,其他步骤都是用户无感知的。
用户第二次访问的认证流程:
假设访问的是Grafana,浏览器里已经存在Keycloak的Cookie和Gitlab的Cookie,没有Grafana的Cookie,显然可以推断出,会经过①②⑤⑥⑦⑧流程,静默完成登录认证,用户全程无感知。
注意这里有前提:SSO Session还在有效期内(⑤流程的验证session),如果不在有效期内,会返回流程③。
四、部署配置
4.1 部署Keycloak
本示例采用Docker Compose快速部署:
# docker-compose.yml
services:
postgres:
image: postgres:15
container_name: keycloak-postgres
restart: always
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: [*这里设置数据库密码*]
volumes:
- ./data/postgres:/var/lib/postgresql/data
networks:
- keycloak-net
keycloak:
image: quay.io/keycloak/keycloak:26.5
container_name: keycloak
command:
- start
restart: always
environment:
KC_DB: postgres
KC_DB_URL_HOST: postgres
KC_DB_URL_DATABASE: keycloak
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: [*这里填上面的数据库密码*]
#前端代理的真实域名
KC_HOSTNAME: https://keycloak.tools.devops.com
KC_HTTP_ENABLED: true
KC_PROXY_HEADERS: xforwarded
# 管理员
KC_BOOTSTRAP_ADMIN_USERNAME: admin
KC_BOOTSTRAP_ADMIN_PASSWORD: [*这里填Keycloak管理员密码*]
# metrics & health
KC_METRICS_ENABLED: "true"
KC_HEALTH_ENABLED: "true"
KC_CACHE: local
# 日志
KC_LOG_LEVEL: INFO
KC_LOG: console,file
KC_LOG_FILE: /opt/keycloak/log/keycloak.log
ports:
- "8082:8080"
volumes:
- ./data/keycloak:/opt/keycloak/data
- ./logs:/opt/keycloak/log
depends_on:
- postgres
networks:
- keycloak-net
networks:
keycloak-net:
driver: bridge
4.2 反向代理(HTTPS)
由于我的测试环境不方便申请域名证书,我们准备自签名证书:
bash
#!/bin/bash
set -e
# ========================
# 1. Root CA
# ========================
openssl genrsa -out rootCA.key 4096
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 3650 -out rootCA.pem \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyOrg/OU=IT/CN=MyRootCA"
# ========================
# 2. Server certificate (for *.tools.devops.com)
# ========================
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyOrg/OU=IT/CN=*.tools.devops.com"
cat > server_ext.cnf <<EOF
subjectAltName=DNS:*.tools.devops.com,DNS:tools.devops.com
extendedKeyUsage=serverAuth
keyUsage=digitalSignature,keyEncipherment
EOF
openssl x509 -req -in server.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial \
-out server.crt -days 825 -sha256 -extfile server_ext.cnf
# ========================
# 3. Combine full chain (for OCI upload)
# ========================
# OCI 里需要:server.crt, server.key, certificate chain
# certificate chain = rootCA.pem
cp rootCA.pem ca-chain.pem
echo "✅ Done!"
echo "Upload to OCI LB:"
echo " Certificate -> server.crt"
echo " Private Key -> server.key"
echo " Certificate Chain -> ca-chain.pem"
echo ""
echo "Install on client:"
echo " Root CA -> rootCA.pem (导入到受信任的根证书颁发机构)"
执行上面的脚本生成*.tools.devops.com域名证书,配置到反向代理上。
我们以OCI负载均衡+Nginx为例:



bash
#Nginx配置文件片段
http {
upstream keycloak_web {
server [Keycloak服务器IP地址]:8082;
}
server {
listen 8080;
server_name keycloak.tools.devops.com;
location / {
proxy_pass http://keycloak_web;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
(可选步骤)根证书通过内网AD或者其他方式植入终端信任列表中。
4.3 管理员Web UI
现在可以通过域名安全的访问管理员Web UI,进行后面的配置:


新建realm:tools-devops,避免直接用master空间。然后切换到tools-devops,后续所有操作都在这个realm中。

五、Active Directory(AD)集成
首先我们将Keycloak对接公司AD域,实现用户从AD同步,直接使用AD账号密码登录Keycloak,避免手动维护多套用户数据。
注意:
1.从AD同步到Keycloak的数据包含user、group、所属关系。
2.后续各个业务系统的RBAC权限控制都会绑定Groups(本示例以infra模拟管理员组,以dev模拟开发组)。
5.1 准备AD测试用户和组
创建如下两个普通用户和两个安全组(zhangsan在infra组,lisi在dev组),创建Domain Users权限的keycloak用户给Keycloak配置使用。

5.2 Keycloak配置LDAP用户联邦
找到User Federation菜单(不同版本位置可能稍有区别),填写LDAP配置:



测试环境可以直接按照上面配置(生产建议用ldaps://ad.example.com:636),然后点击Test authentication,返回"Successfully connected to LDAP"即成功。
5.3 LDAP属性映射
Mappers菜单可以根据需要定义属性映射,比如我们手动添加first name:


手动添加groups:


点击Sync菜单先把Groups同步过来:


由于之前设置的Full sync period是86400,也就是每天自动同步一次。这里直接点击Sync all users立即手动触发全量同步:

回到Users菜单,可以看到用户和所属组都正确同步过来了:


接下来我们会在开源身份认证与访问管理平台 - Keycloak(二)中演示与各个系统的集成。