开源身份认证与访问管理平台 - Keycloak(一)

目录

一、简介

二、核心概念

[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)

三、Keycloak架构

[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有自己的用户、客户端、角色和配置,互相隔离互不影响。

  • master Realm:管理员专用,用于管理其他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(二)中演示与各个系统的集成。

相关推荐
rustfs1 小时前
MinIO 国产平替,RustFS 发布 Beta 版本啦
分布式·docker·云原生·rust·开源
gwjcloud2 小时前
Kubernetes从入门到精通(基础篇)02
云原生·容器·kubernetes
Hungry_Shark2 小时前
Windows上Docker安装失败:DockerDesktop must beowned by an elevated account
windows·docker
OpenCSG2 小时前
Kimi K2.6:月之暗面发布的原生多模态智能体模型
人工智能·开源·大模型·ai技术·kimi k2.6
苏渡苇2 小时前
关于Docker镜像仓库
docker·镜像仓库·docker私有镜像仓库
telllong2 小时前
3分钟理解服务网格Istio
云原生·istio
流放深圳2 小时前
CentOS7 安装 Redis Stack
docker·redisstack
阿川20152 小时前
词元经济重新定义AI原生,继云原生后企业IT再次变局
云原生·ai-native
布吉岛的石头2 小时前
云原生面试考点:K8s 核心组件 + Deployment 实战
云原生·面试·kubernetes