Keycloak TLS

验证:未记录
适用版本
未记录
验证范围
尚未登记验证记录。

本文缩写(英文全称与中文含义)
缩写 英文全称/名称 中文含义
ACME Automatic Certificate Management Environment 自动化证书管理协议
AD Active Directory 微软活动目录
CA Certificate Authority 证书颁发机构
DB Database 数据库
HTTP Hypertext Transfer Protocol 超文本传输协议
HTTPS Hypertext Transfer Protocol Secure 使用 TLS 加密的 HTTP
IdP Identity Provider 身份提供方
JDBC Java Database Connectivity Java 数据库连接接口
LDAP Lightweight Directory Access Protocol 轻量级目录访问协议
LDAPS LDAP over TLS 通过 TLS 保护的 LDAP
OIDC OpenID Connect 基于 OAuth 2.0 的身份认证协议
SAN Subject Alternative Name 证书主题备用名称,用于声明域名或 IP
SMTP Simple Mail Transfer Protocol 简单邮件传输协议
TLS Transport Layer Security 传输层安全协议
URL Uniform Resource Locator 统一资源定位符,通常指访问地址
https://www.keycloak.org/server/enabletls
https://www.keycloak.org/server/hostname
https://www.keycloak.org/server/reverseproxy
https://www.keycloak.org/server/db
https://www.keycloak.org/server/all-config

1. Important Points#

Keycloak 企业部署里 TLS 不只是浏览器访问 HTTPS。至少有 4 条链路要明确:

browser / app -> Keycloak:
    public HTTPS endpoint

reverse proxy / ingress -> Keycloak:
    edge termination or re-encrypt

Keycloak -> PostgreSQL:
    JDBC TLS and CA verification

Keycloak -> LDAP / AD / upstream IdP / SMTP:
    LDAPS / HTTPS / SMTP TLS

production principles:

use trusted CA certificates
keep hostname stable
verify certificates and hostnames
monitor certificate expiry
rotate certs before expiry
do not use insecure TLS flags in production

2. Server Configuration#

TLS terminated at Keycloak#

hostname=sso.example.com
http-enabled=false
https-certificate-file=/etc/keycloak/tls/tls.crt
https-certificate-key-file=/etc/keycloak/tls/tls.key
health-enabled=true
metrics-enabled=true

File layout:

/etc/keycloak/tls/
    tls.crt
    tls.key
    ca.crt

permissions:
    tls.key readable only by keycloak user
    certificate files managed by cert-manager / ACME / secret manager

TLS terminated at reverse proxy#

hostname=sso.example.com
http-enabled=true
proxy-headers=xforwarded

reverse proxy checklist:

edge:
    TLS certificate belongs to sso.example.com
    redirect HTTP to HTTPS
    set X-Forwarded-For
    set X-Forwarded-Proto=https
    set X-Forwarded-Host=sso.example.com

Keycloak:
    trusts forwarded headers only from controlled proxy
    hostname matches external URL
    admin console tested behind proxy

Do not expose the internal HTTP port directly to users when TLS is terminated at the proxy.

3. Client Configuration / Verify#

OIDC discovery:

curl -fsS https://sso.example.com/realms/prod/.well-known/openid-configuration

Certificate verify:

openssl s_client -connect sso.example.com:443 -servername sso.example.com </dev/null

Expected:

Verify return code: 0 (ok)
issuer is expected company/public CA
subject/SAN contains sso.example.com
certificate expires later than rotation window

Database TLS:

db=postgres
db-url=jdbc:postgresql://postgres.example.com:5432/keycloak?sslmode=verify-full&sslrootcert=/etc/keycloak/db-ca/ca.crt
db-username=keycloak
db-password=${KC_DB_PASSWORD}

LDAP TLS:

LDAP URL:
    ldaps://ad.example.com:636

trust:
    AD server certificate chains to trusted CA
    hostname matches certificate SAN
    bind account has least privilege

4. Java#

Spring Security OIDC resource server example:

spring.security.oauth2.resourceserver.jwt.issuer-uri=https://sso.example.com/realms/prod

Custom CA:

keytool -importcert -alias company-root-ca -file company-root-ca.crt -keystore truststore.p12 -storetype PKCS12

java -Djavax.net.ssl.trustStore=truststore.p12 -Djavax.net.ssl.trustStorePassword=changeit -jar order-api.jar

Do not disable hostname verification in production.

5. Python#

Python requests with CA bundle:

import requests

issuer = "https://sso.example.com/realms/prod"
resp = requests.get(
    f"{issuer}/.well-known/openid-configuration",
    timeout=5,
    verify="/etc/ssl/company-ca.pem",
)
resp.raise_for_status()
print(resp.json()["issuer"])

Runtime:

export SSL_CERT_FILE=/etc/ssl/company-ca.pem
export REQUESTS_CA_BUNDLE=/etc/ssl/company-ca.pem

Never use verify=False in production.

6. Go#

Go custom CA:

package main

import (
	"crypto/tls"
	"crypto/x509"
	"net/http"
	"os"
)

func clientWithCA(caPath string) (*http.Client, error) {
	pem, err := os.ReadFile(caPath)
	if err != nil {
		return nil, err
	}
	roots := x509.NewCertPool()
	roots.AppendCertsFromPEM(pem)

	return &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{
				MinVersion: tls.VersionTLS12,
				RootCAs:    roots,
			},
		},
	}, nil
}

Do not set InsecureSkipVerify: true in production.

7. Node.js#

Node.js with custom CA:

export NODE_EXTRA_CA_CERTS=/etc/ssl/company-ca.pem
node server.js

Fetch OIDC discovery:

const issuer = "https://sso.example.com/realms/prod";

const resp = await fetch(`${issuer}/.well-known/openid-configuration`);
if (!resp.ok) {
  throw new Error(`OIDC discovery failed: ${resp.status}`);
}

const discovery = await resp.json();
console.log(discovery.issuer);

Never use NODE_TLS_REJECT_UNAUTHORIZED=0 or rejectUnauthorized: false in production.

8. Rotation Checklist#

before rotation:
    check all clients trust the new CA/intermediate
    update Keycloak TLS secret or certificate files
    update DB / LDAP CA bundles if needed
    confirm certificate SAN includes hostname

during rotation:
    apply secret/certificate
    restart or reload component if needed
    verify OIDC discovery
    verify browser login
    verify app token validation

after rotation:
    monitor login failures and TLS errors
    remove old cert after overlap window
    update expiry dashboard

搜索文档

输入关键词,搜索所有文档。

↑ ↓ 选择 · Enter 打开 · Esc 关闭