1. ユーザーフェデレーション — 概要
ユーザーフェデレーションによるKeycloakの有効化外部ユーザーデータベースに接続するLDAP、Active Directory、カスタム データベースなど。すべてのユーザーをKeycloakにインポートする代わりに、外部ソースから直接認証できます。
ユーザー フェデレーションを設定するには、次の場所に移動します。管理コンソール → ユーザーフェデレーション.
1.1 ユーザー フェデレーションが必要な理由は何ですか?
| 理由 | 説明する |
|---|---|
| ユーザー管理を一元化する | LDAP/AD はすでに企業内の主要なユーザー ソースである → 重複する必要はありません |
| 現在のシステムをそのまま維持する | ユーザーをKeycloakに移行する必要はありません |
| 単一の真実の情報源 | ユーザーデータは 1 か所にのみ存在し、不整合を回避します |
| ケルベロス SSO | Active Directory からの Kerberos 認証の統合 |
1.2 フェデレーションプロバイダーの種類
| プロバイダー | 説明する |
|---|---|
| LDAP | OpenLDAP、389 Directory Server、および LDAP 準拠サーバーをサポート |
| アクティブディレクトリ | Microsoft Active Directory (LDAP プロトコル + AD 固有のマッパーを使用) |
| SSSD | システム セキュリティ サービス デーモン — FreeIPA/Red Hat IdM の統合 |
| カスタム ユーザー ストレージ SPI | 任意のデータベースに接続するための独自のプロバイダーを作成します |
2. LDAPプロバイダーの追加
入力管理コンソール → ユーザー フェデレーション → LDAP プロバイダーの追加.
2.1 一般的なオプション
| 設定 | 説明する | サンプル値 |
|---|---|---|
| コンソールの表示名 | 管理コンソールに表示される名前 | 企業LDAP |
| 優先度 | プロバイダが多い場合の優先順位 | 0(最高) |
| 有効 | プロバイダーの有効化/無効化 | の上 |
| ユーザーをインポートする | LDAPユーザーをKeycloakローカルデータベースにインポートする | の上 |
2.2 接続設定
# Connection URL
Connection URL: ldap://ldap.example.com:389
# Hoặc LDAPS (SSL):
Connection URL: ldaps://ldap.example.com:636
# Bind Type
Bind Type: simple
# Bind DN — tài khoản để Keycloak kết nối LDAP
Bind DN: cn=admin,dc=example,dc=com
# Bind Credential — mật khẩu
Bind Credential: ********
接続プールの設定:
| 設定 | 説明する | デフォルト |
|---|---|---|
| 接続プーリング | 接続プールを有効にしてパフォーマンスを最適化する | の上 |
| 接続プールの認証 | 認証された接続用のプール | 単純。単純 |
| 接続プールのデバッグ | 接続プールのデバッグをログに記録する | オフ |
| 接続プールの初期サイズ | 最初に初期化された接続の数 | 1 |
| 接続プールの最大サイズ | 最大接続数 | 1000 |
| 接続プールのタイムアウト | プールから接続を取得するまでの待ち時間 | 30000MS |
2.3 SSL/LDAPS設定
LDAPS (ポート 636) に接続するには、CA 証明書を Keycloak トラストストアにインポートする必要があります。
# Tải CA certificate từ LDAP server
openssl s_client -connect ldap.example.com:636 -showcerts < /dev/null 2>/dev/null | \
openssl x509 -outform PEM > ldap-ca.pem
# Import vào Java truststore
keytool -import -alias ldap-ca \
-keystore /opt/keycloak/conf/truststore.jks \
-file ldap-ca.pem \
-storepass changeit -noprompt
# Hoặc sử dụng PEM truststore (Keycloak 24+)
# Đặt file PEM vào /opt/keycloak/conf/truststores/
cp ldap-ca.pem /opt/keycloak/conf/truststores/
トラストストアを使用するように Keycloak を構成します。
# keycloak.conf
# Java keystore
spi-truststore-file-file=/opt/keycloak/conf/truststore.jks
spi-truststore-file-password=changeit
spi-truststore-file-type=JKS
# Hoặc PEM directory (Keycloak 24+)
truststore-paths=/opt/keycloak/conf/truststores
2.4 StartTLS を使用する
LDAPS (ポート 636) の代わりに、次のものを使用できます。TLSの開始ポート 389:
Connection URL: ldap://ldap.example.com:389
Use StartTLS: ON
StartTLS は、通常の LDAP 接続を同じポート 389 上の暗号化された接続にアップグレードします。
3. LDAP検索設定
| 設定 | 説明する | サンプル値 |
|---|---|---|
| ユーザーDN | Keycloakがユーザーを検索するベースDN | ou=人、dc=例、dc=com |
| ユーザーオブジェクトクラス | ユーザーエントリのLDAPオブジェクトクラス | inetOrgperson、organizationalperson |
| ユーザー名のLDAP属性 | LDAP 属性にはユーザー名が含まれます | UID(LDAP) /sAMアカウント名(広告) |
| RDN LDAP 属性 | RDN (相対識別名) に使用される属性 | UID(LDAP) /CN(広告) |
| UUID LDAP 属性 | 属性は一意のIDとして使用されます | エントリUUID(LDAP) /オブジェクトGUID(広告) |
| 検索範囲 | 1 つのレベルまたはサブツリー | サブツリー |
| カスタムユーザーLDAPフィルター | ユーザーをフィルタリングするための追加の LDAP フィルタ | (&(objectClass=person)(memberOf=cn=app-users,ou=Groups,dc=example,dc=com)) |
| 読み取りタイムアウト | LDAP読み取り操作のタイムアウト | 30000MS |
3.1 Active Directoryの設定
選ぶときはベンダー = Active Directory, Keycloak は適切な値を自動的に構成します。
Username LDAP attribute: cn
RDN LDAP attribute: cn
UUID LDAP attribute: objectGUID
User Object Classes: person, organizationalPerson, user
Users DN: cn=Users,dc=corp,dc=example,dc=com
4. ストレージモード
Keycloakは、KeycloakがLDAPと対話する方法を決定する3つのストレージモードをサポートしています。
| モード | LDAPから読み取る | LDAPリバースロギング | Keycloak DBへのインポート | ユースケース |
|---|---|---|---|---|
| 読み取り専用 | ✅ | ❌ | ✅ (キャッシュ) | LDAP は単一ソースであり、ユーザーが Keycloak 経由で情報を変更することはできません |
| 書き込み可能 | ✅ | ✅ | ✅ | ユーザーが情報 (パスワード、プロファイル) を変更し、LDAP に書き戻すことができるようにします。 |
| 未同期 | ✅ | ❌ | ✅ | LDAP からユーザーをインポートし、Keycloak DB にのみ変更を保存します (ライトバックなし) |
4.1 編集モード
編集モードは、ユーザーまたは管理者が情報を変更するときの動作を規制します。
READ_ONLY:
- User không thể đổi password qua Keycloak
- Admin không thể edit user attributes
- Mọi thay đổi phải thực hiện trực tiếp trên LDAP
WRITABLE:
- User có thể đổi password → Keycloak ghi ngược về LDAP
- Admin edit user attributes → cập nhật LDAP
- Cẩn thận với password policy: phải match giữa Keycloak và LDAP
UNSYNCED:
- User đổi password → chỉ lưu trong Keycloak DB
- Đăng nhập: Keycloak thử password local trước, nếu fail thì thử LDAP
- Phù hợp khi muốn dần migrate users sang Keycloak
5. 同期設定
Keycloakは、次の2つのメカニズムによってLDAPからユーザーを同期できます。
5.1 定期的な完全同期
# Import toàn bộ users từ LDAP vào Keycloak DB
Periodic Full Sync: ON
Full Sync Period: 604800 # seconds (7 ngày)
5.2 変更されたユーザーの定期的な同期
# Chỉ đồng bộ users có thay đổi (dựa vào modifyTimestamp)
Periodic Changed Users Sync: ON
Changed Users Sync Period: 86400 # seconds (1 ngày)
5.3 手動同期
同期は、管理コンソールまたは CLI 経由で手動でトリガーできます。
# Trigger full sync qua Admin REST API
curl -X POST "http://localhost:8080/admin/realms/my-realm/user-storage/${LDAP_PROVIDER_ID}/sync?action=triggerFullSync" \
-H "Authorization: Bearer ${ACCESS_TOKEN}"
# Trigger changed users sync
curl -X POST "http://localhost:8080/admin/realms/my-realm/user-storage/${LDAP_PROVIDER_ID}/sync?action=triggerChangedUsersSync" \
-H "Authorization: Bearer ${ACCESS_TOKEN}"
6. LDAP マッパー
LDAP マッパーが Keycloak をどのように定義するかLDAP属性をKeycloakユーザーモデルにマッピングする。これは、LDAP フェデレーションを構成する場合に最も重要な部分です。
6.1 ユーザー属性 LDAP マッパー
LDAP 属性を Keycloak ユーザー属性にマップします。
Mapper Type: user-attribute-ldap-mapper
LDAP Attribute: mail
User Model Attribute: email
Read Only: true
Always Read Value From LDAP: false
Is Mandatory In LDAP: true
デフォルトのマッパーは自動的に作成されます。
| マッパー名 | LDAP 属性 | キークローク属性 |
|---|---|---|
| ユーザー名。ユーザー名 | UID / sAMアカウント名 | ユーザー名。ユーザー名 |
| 電子メール | 郵便 | 電子メール |
| ファーストネーム | 名 / CN | ファーストネーム |
| 苗字 | すん | 苗字 |
| 作成日 | タイムスタンプの作成 | タイムスタンプの作成 |
| 日付を変更する | タイムスタンプの変更 | タイムスタンプの変更 |
6.2 フルネーム LDAP マッパー
LDAP のマップCN(通称)Keycloakへファーストネーム + 苗字:
Mapper Type: full-name-ldap-mapper
LDAP Full Name Attribute: cn
Read Only: true
Write Only: false
LDAP のみが使用可能な場合に役立ちますCN分離せずに名/すん.
6.3 グループLDAPマッパー
LDAP グループを Keycloak グループに同期します。
Mapper Type: group-ldap-mapper
LDAP Groups DN: ou=Groups,dc=example,dc=com
Group Name LDAP Attribute: cn
Group Object Classes: groupOfNames
Membership LDAP Attribute: member
Membership Attribute Type: DN
Membership User LDAP Attribute: uid
Mode: READ_ONLY
User Groups Retrieve Strategy: LOAD_GROUPS_BY_MEMBER_ATTRIBUTE
Drop non-existing groups during sync: false
Groups Path: /
ユーザーグループの取得戦略オプション:
| 戦略 | 説明する |
|---|---|
| LOAD_GROUPS_BY_MEMBER_ATTRIBUTE | メンバー属性に基づいて LDAP からグループをロードします |
| GET_GROUPS_FROM_USER_MEMBEROF_ATTRIBUTE | 読むメンバーのユーザーエントリの属性 |
| LOAD_GROUPS_BY_MEMBER_ATTRIBUTE_RECURSIVELY | グループを再帰的にロードします (ネストされたグループ) |
6.4 ロールLDAPマッパー
LDAP ロール/グループを Keycloak レルム ロールに同期します。
Mapper Type: role-ldap-mapper
LDAP Roles DN: ou=Roles,dc=example,dc=com
Role Name LDAP Attribute: cn
Role Object Classes: groupOfNames
Membership LDAP Attribute: member
Membership Attribute Type: DN
Membership User LDAP Attribute: uid
Mode: READ_ONLY
Use Realm Roles Mapping: true
Client ID: (để trống nếu dùng realm roles)
6.5 ハードコードされた LDAP ロールマッパー
固定役割を自動的に割り当てる全てLDAP プロバイダーからのユーザー:
Mapper Type: hardcoded-ldap-role-mapper
Role: realm-role-name
# Hoặc client role:
Role: client-id.client-role-name
ロール マーカーを使用して LDAP ユーザーとローカル ユーザーを区別する場合に便利です。
6.6 msad-user-account-control-mapper
特別なマッパーアクティブディレクトリ、 ハンドルユーザーアカウントコントロール属性:
Mapper Type: msad-user-account-control-mapper
# Xử lý:
# - Account enabled/disabled status
# - Password expired status
# - Account locked status
# - Require user to change password at next login
このマッパーはビットマスクを読み取りますユーザーアカウントコントロールKeycloakユーザーステータスにマッピングするADの:
| ADフラグ(ビット) | キークロークの動作 |
|---|---|
責任を負う(0x0002) | ユーザーはKeycloakで無効になっています |
ロックアウト(0x0010) | ユーザーがロックされています |
PASSWORD_EXPIRED | ユーザーはログイン時にパスワードを変更する必要があります |
6.7 証明書-LDAP-マッパー
X.509 認証の LDAP 証明書属性を Keycloak ユーザー属性にマップします。
Mapper Type: certificate-ldap-mapper
LDAP Attribute: userCertificate
User Model Attribute: usercertificate
Is DER Formatted: true
Always Read Value From LDAP: true
7. パスワードのハッシュ化
LDAP フェデレーションを使用する場合、パスワード ハッシュにはいくつかの重要な特性があります。
| シナリオ | パスワードハッシュ | 注記 |
|---|---|---|
| 読み取り専用モード | パスワードは常に LDAP サーバーで直接検証されます。 | Keycloakはパスワードハッシュを保存しません |
| 書き込み可能モード | パスワードは、LDAP パスワード ポリシーに従って LDAP に記録されます。 | LDAPサーバーはハッシュを実行します |
| 非同期モード | Keycloakハッシュを使用してKeycloak DBに保存された新しいパスワード | 古いパスワードは引き続き LDAP 経由で検証されます |
# Kiểm tra password policy trên LDAP (OpenLDAP)
ldapsearch -x -H ldap://localhost:389 \
-D "cn=admin,dc=example,dc=com" -W \
-b "cn=config" "(objectClass=olcGlobal)" olcPasswordHash
# Output ví dụ:
# olcPasswordHash: {SSHA}
8. SSSD と FreeIPA の統合
Keycloakはとの統合をサポートしていますSSSD (システム セキュリティ サービス デーモン)D-Bus インターフェース経由で、FreeIPA または Red Hat Identity Manager からユーザーを認証できるようになります。
8.1 前提条件
# Cài đặt SSSD trên Keycloak server
sudo dnf install sssd sssd-dbus
# Cấu hình SSSD (/etc/sssd/sssd.conf)
[sssd]
services = nss, pam, ifp
domains = example.com
[domain/example.com]
id_provider = ipa
auth_provider = ipa
access_provider = ipa
ipa_domain = example.com
ipa_server = ipa.example.com
[ifp]
allowed_uids = root, keycloak
user_attributes = +mail, +givenname, +sn, +telephoneNumber
8.2 SSSD フェデレーションプロバイダーの構成
管理コンソールで、追加しますSSSDフェデレーションプロバイダー — KeycloakはD-Bus経由でSSSDと通信し、次のことを行います。
- ユーザーの認証 (PAM)
- ユーザー属性の取得 (InfoPipe)
- グループメンバーシップを取得する
9. ケルベロスブリッジ
キークロークが使えるケルベロス認証LDAP フェデレーションと併用すると、ユーザーは Kerberos チケット (SPNEGO) を使用して自動的にログインできるようになります。
9.1 LDAP を使用した Kerberos の構成
# Trong LDAP provider settings
Allow Kerberos authentication: ON
Kerberos Realm: EXAMPLE.COM
Server Principal: HTTP/[email protected]
KeyTab: /etc/keycloak/keycloak.keytab
Use Kerberos for password authentication: ON
# Tạo keytab cho Keycloak service principal
kadmin.local -q "addprinc -randkey HTTP/[email protected]"
kadmin.local -q "ktadd -k /etc/keycloak/keycloak.keytab HTTP/[email protected]"
# Set permissions
chown keycloak:keycloak /etc/keycloak/keycloak.keytab
chmod 600 /etc/keycloak/keycloak.keytab
9.2 SPNEGO のブラウザ設定
Firefox:
1. about:config
2. network.negotiate-auth.trusted-uris = .example.com
3. network.negotiate-auth.delegation-uris = .example.com
Chrome / Edge:
1. Policy: AuthServerAllowlist = *.example.com
2. Hoặc command line: --auth-server-whitelist="*.example.com"
10. カスタム ユーザー ストレージ SPI
LDAP が十分でない場合は、次のように書くことができますカスタム ユーザー ストレージ プロバイダーあらゆるデータ ソース (SQL データベース、REST API、レガシー システムなど) に接続できます。
10.1 SPI インターフェース
// UserStorageProviderFactory — tạo provider instances
public class MyUserStorageProviderFactory
implements UserStorageProviderFactory<MyUserStorageProvider> {
@Override
public String getId() {
return "my-user-storage";
}
@Override
public MyUserStorageProvider create(KeycloakSession session,
ComponentModel model) {
return new MyUserStorageProvider(session, model);
}
}
// UserStorageProvider — implement các interfaces cần thiết
public class MyUserStorageProvider implements
UserStorageProvider,
UserLookupProvider,
CredentialInputValidator,
UserQueryProvider {
@Override
public UserModel getUserByUsername(RealmModel realm, String username) {
// Query external database
ExternalUser extUser = externalDb.findByUsername(username);
if (extUser == null) return null;
// Wrap vào Keycloak UserModel
return new UserAdapter(session, realm, model, extUser);
}
@Override
public boolean isValid(RealmModel realm, UserModel user,
CredentialInput input) {
if (!supportsCredentialType(input.getType())) return false;
// Verify password với external system
return externalDb.verifyPassword(
user.getUsername(),
input.getChallengeResponse()
);
}
}
10.2 カスタムプロバイダーのデプロイ
# Build JAR
mvn clean package
# Copy vào Keycloak providers directory
cp target/my-user-storage.jar /opt/keycloak/providers/
# Rebuild Keycloak
/opt/keycloak/bin/kc.sh build
11. kcadm.sh を使用して LDAP を構成する
使用kcadm.shコマンドライン経由で LDAP フェデレーションを設定するには、次の手順を実行します。
# Đăng nhập
kcadm.sh config credentials \
--server http://localhost:8080 \
--realm master \
--user admin \
--password admin
# Tạo LDAP provider
kcadm.sh create components -r my-realm \
-s name="Corporate LDAP" \
-s providerId=ldap \
-s providerType=org.keycloak.storage.UserStorageProvider \
-s 'config.vendor=["other"]' \
-s 'config.connectionUrl=["ldap://ldap.example.com:389"]' \
-s 'config.bindDn=["cn=admin,dc=example,dc=com"]' \
-s 'config.bindCredential=["admin_password"]' \
-s 'config.usersDn=["ou=People,dc=example,dc=com"]' \
-s 'config.userObjectClasses=["inetOrgPerson, organizationalPerson"]' \
-s 'config.usernameLDAPAttribute=["uid"]' \
-s 'config.rdnLDAPAttribute=["uid"]' \
-s 'config.uuidLDAPAttribute=["entryUUID"]' \
-s 'config.editMode=["READ_ONLY"]' \
-s 'config.syncRegistrations=["false"]' \
-s 'config.searchScope=["2"]' \
-s 'config.importEnabled=["true"]' \
-s 'config.enabled=["true"]' \
-s 'config.priority=["0"]' \
-s 'config.fullSyncPeriod=["604800"]' \
-s 'config.changedSyncPeriod=["86400"]'
# Lấy LDAP provider ID
LDAP_ID=$(kcadm.sh get components -r my-realm \
--fields id,name \
-q providerType=org.keycloak.storage.UserStorageProvider \
| jq -r '.[0].id')
# Thêm group mapper
kcadm.sh create components -r my-realm \
-s name="group-mapper" \
-s providerId=group-ldap-mapper \
-s providerType=org.keycloak.storage.ldap.mappers.LDAPStorageMapper \
-s parentId=$LDAP_ID \
-s 'config.groups.dn=["ou=Groups,dc=example,dc=com"]' \
-s 'config.group.name.ldap.attribute=["cn"]' \
-s 'config.group.object.classes=["groupOfNames"]' \
-s 'config.membership.ldap.attribute=["member"]' \
-s 'config.membership.attribute.type=["DN"]' \
-s 'config.membership.user.ldap.attribute=["uid"]' \
-s 'config.mode=["READ_ONLY"]' \
-s 'config.drop.non.existing.groups.during.sync=["false"]'
# Trigger full sync
kcadm.sh create user-storage/$LDAP_ID/sync -r my-realm \
-s action=triggerFullSync
12. LDAP 問題のトラブルシューティング
12.1 接続の問題
| エラー | 理由 | 解決 |
|---|---|---|
javax.naming.CommunicationException | LDAPサーバーに接続できません | ネットワーク、ファイアウォール、ポート 389/636 を確認してください |
javax.naming.AuthenticationException | 間違ったバインド DN またはバインド資格情報 | バインド資格情報を検証しますldapsearch |
SSLハンドシェイク例外 | 証明書が信頼されていません | CA 証明書をトラストストアにインポートする |
接続タイムアウト | LDAPサーバーが応答しない | 接続タイムアウトを増やし、DNS を確認してください |
# Test LDAP connection
ldapsearch -x -H ldap://ldap.example.com:389 \
-D "cn=admin,dc=example,dc=com" -W \
-b "ou=People,dc=example,dc=com" \
"(objectClass=inetOrgPerson)" uid mail cn
# Test LDAPS connection
ldapsearch -x -H ldaps://ldap.example.com:636 \
-D "cn=admin,dc=example,dc=com" -W \
-b "dc=example,dc=com" "(uid=testuser)"
# Bật debug logging trong Keycloak
bin/kc.sh start-dev \
--log-level=org.keycloak.storage.ldap:DEBUG
12.2 同期の失敗
| エラー | 理由 | 解決 |
|---|---|---|
ユーザー ... すでに存在します | LDAP とローカル ユーザーの間でユーザー名が競合する | ローカル ユーザーを削除するか、ユーザー名のマッピングを変更します |
サイズ制限を超えました | LDAP サーバーは返される結果の数を制限します | LDAP サーバーでページングを構成するか、LDAP フィルターを追加して範囲を縮小します |
紹介 | LDAP は結果ではなく紹介を返します | セット紹介=フォロー接続設定で |
12.3 マッパーの問題
# Kiểm tra LDAP attributes có tồn tại
ldapsearch -x -H ldap://ldap.example.com:389 \
-D "cn=admin,dc=example,dc=com" -W \
-b "uid=testuser,ou=People,dc=example,dc=com" \
"*" "+"
# Kiểm tra group membership
ldapsearch -x -H ldap://ldap.example.com:389 \
-D "cn=admin,dc=example,dc=com" -W \
-b "ou=Groups,dc=example,dc=com" \
"(member=uid=testuser,ou=People,dc=example,dc=com)" cn
13. ベストプラクティス
- 常に LDAPS または StartTLS を使用する— 資格情報を平文で送信しないようにします
- 別のサービス アカウントを使用するバインド DN の場合 — 管理者アカウントを使用しないでください
- 検索範囲を制限する— カスタム ユーザー LDAP フィルターを使用して、必要なユーザーのみをインポートします
- 接続プールをオンにする— 接続作成のオーバーヘッドを削減します
- 同期期間を適切に構成する— 短すぎると LDAP に大きな負荷がかかり、長すぎるとデータが古くなります
- 同期ログを監視する— Keycloakは同期プロセスに関する詳細をログに記録します
- 最初に READ_ONLY でテストします— 最初に設定するときは、WRITABLE を転送する前に READ_ONLY を使用して検証します。
- メジャー同期の前にKeycloak DBをバックアップする— 完全同期では数千のユーザーをインポートできます