既存のActive DirectoryやLDAPをそのまま活かして、KeycloakをID基盤に据えたい。よくある要件ですが、編集モードや同期戦略、AD特有の属性を取り違えると運用が破綻します。実構築で押さえてきた勘所を整理します。
エンタープライズでKeycloakを導入する際、まず直面するのが「既存のActive Directory(AD)やLDAPをどう組み込むか」です。ユーザーをKeycloakに全移行するのではなく、既存ディレクトリを真実の源(source of truth)として残したまま認証基盤を載せ替えるケースが大半でしょう。KeycloakのUser Federation機能は、この統合を標準で担います。本稿では編集モード、LDAPマッパー、同期戦略、そしてAD特有の落とし穴を、実構築の目線で掘り下げます。なお設定名やUIはバージョンで細部が変わるため、現行のQuarkusベース(WildFly版は非推奨)を前提に、最終的な確認は公式のServer Administration Guideで行ってください。
01User Federationの全体像
KeycloakのUser Federationは、外部ストレージ(LDAP/AD)のユーザーをKeycloakの共通ユーザーモデルにマッピングして扱う仕組みです。認証時はKeycloakがLDAPにバインドしてパスワード検証を委譲し、ユーザー属性やグループは設定次第でインポートまたはオンデマンド参照されます。重要なのは、Keycloakはパスワードを取り込まないという原則です。パスワード検証は常にLDAPサーバー側で行われ、Keycloakのローカルストアにパスワードが保存されることはありません。この点はセキュリティレビューでもよく問われるので、最初に押さえておきます。
1つのRealmに複数のLDAP/ADプロバイダを束ねることもできます。例えば「本社のAD」と「子会社の別フォレスト」を同一Realmに федерートし、ユーザー名の衝突を運用ルールで避ける、といった構成です。プロバイダには優先度(priority)があり、同名ユーザーがいた場合の解決順序を決めます。
02編集モード:READ_ONLY / WRITABLE / UNSYNCED
LDAPプロバイダには3つの編集モード(Edit Mode)があり、これがユーザー属性の書き込み挙動を決定します。設計初期に最も議論すべきポイントです。
- READ_ONLY:Keycloak側から属性やパスワードを変更できません。LDAP/ADが完全な真実の源で、更新は既存の運用フロー(AD管理ツール等)で行う場合の既定選択です。
- WRITABLE:Keycloakでの属性変更・パスワードリセットがLDAPへ書き戻されます。セルフサービスのプロフィール更新やパスワード変更をKeycloak側に寄せたい場合に使いますが、書き込み権限を持つバインドアカウントとスキーマ整合が前提です。
- UNSYNCED:属性やパスワードの変更をKeycloakのローカルDBに保持し、LDAPには書き戻しません。LDAP側を汚さずにKeycloak独自の属性を上書きしたい、といった折衷案です。
03同期戦略:full sync と changed users sync
Import modeを有効にすると、LDAPユーザーがKeycloakのDBにインポートされます(オンデマンド参照との差はストレージモードで決まります)。インポートを使う場合、同期(Sync)の設計が運用品質を左右します。Keycloakが提供する同期は2種類です。
- Full sync(全同期):LDAPの全ユーザーを走査してインポート/更新します。初回移行や、changed syncが検知できない削除・大規模変更の是正に使います。ユーザー数が多いと負荷が大きいため、実行時間帯に注意が必要です。
- Changed users sync(差分同期):前回同期以降に変更されたユーザーだけを取り込みます。ADの
whenChangedやLDAPのmodifyTimestampを基準に判定するため、頻度高く回しても軽量です。
両者は定期実行(periodic sync)として個別に間隔を設定できます。実務では「差分同期を短周期(例:数分〜十数分)」「全同期を夜間の低頻度(例:1日1回)」と組み合わせるのが定石です。ただし差分同期はLDAPからのエントリ削除を確実には拾えないことがあるため、削除の反映は全同期に頼る、という前提で設計します。
04LDAPマッパー:属性・氏名・グループ・ロール
LDAPマッパーは、LDAPのエントリとKeycloakのユーザーモデルの橋渡しをする拡張点です。プロバイダ作成時に既定のマッパー群が自動生成され、追加・編集・削除できます。主要なものを押さえます。
- user-attribute-ldap-mapper:LDAP属性(
mail、snなど)をKeycloakのユーザー属性へ1対1でマッピングします。UPN(userPrincipalName)を独自属性として持たせたい場合もこれを使います。 - full-name-ldap-mapper:AD の
cnのような1つの氏名属性を、KeycloakのfirstName/lastNameに分解します。姓名の順序や分割規則が日本語環境で意図とずれることがあるので検証が要ります。 - group-ldap-mapper:LDAPグループをKeycloakのグループへマッピングします(後述)。
- role-ldap-mapper:LDAPグループをKeycloakのロールへマッピングします。グループとして扱うかロールとして扱うかは権限モデル次第で、ロール/グループ/属性の使い分けの設計と一体で考えます。
05group-ldap-mapperの深掘り
グループ同期は要件が細かく、設定を取り違えると「グループが二重にできる」「メンバーが反映されない」といったトラブルの温床になります。group-ldap-mapperの主要な設定軸は次のとおりです。
- Mode(モード):
READ_ONLY(LDAPを正としてKeycloakへ読み込む)、LDAP_ONLY(グループとメンバーシップはLDAPだけで管理し、Keycloak側で作らない)、IMPORT(LDAPから読み込むがKeycloak側にも保持)があります。多くの現場ではREAD_ONLYが起点になります。 - Membership属性の型(DN or UID):グループの
member属性がメンバーをDNで持つか、UID値で持つかを指定します。ADは通常DNベースです。 - Member-Of戦略:ユーザー側の
memberOf属性からメンバーシップを引く方式です。ADのようにmemberOfが使える環境では、グループ側を舐めるより効率的なことがあります。 - Preserve Group Inheritance(グループ階層の保持):LDAPのネストしたグループ構造をKeycloakのグループ階層として再現するか、フラットに展開するかを決めます。LDAP側のスキーマが階層を許すことが前提です。
また、異なるOUを指す複数のgroup-ldap-mapperを1プロバイダに設定し、グループツリー上で別々の「フォルダ」として見せることもできます。組織ごとにグループのOUが分かれているエンタープライズADでは有効な構成です。挙動の厳密な定義は実装(GroupLDAPStorageMapperのJavadoc)まで当たると迷いがありません。
06Active Directory特有の勘所:objectGUIDとUPN
ADを接続する場合、汎用LDAPとは異なる設定が必要です。押さえるべき代表的な項目を挙げます。
- UUID LDAP Attribute = objectGUID:ユーザーを一意に識別する不変IDとして
objectGUIDを指定します。ここをcnやsAMAccountNameのような可変値にすると、ユーザー名変更やOU移動でKeycloak側の同一性が壊れ、フェデレーションIDが二重化します。objectGUIDはバイナリ属性で、Keycloakは対象がUUID属性であれば自動でUUIDとしてデコードします。 - Username LDAP Attribute = sAMAccountName:多くのAD環境ではログイン名に
sAMAccountNameを使います。UPNログインを要件とする場合はuserPrincipalNameを別途マッピングして扱います。 - User Object Classes:
person, organizationalPerson, userが典型です。 - バインド方式:ADへの接続はUPN形式(例:
admin@corp.example.com)またはDN形式が使えます。
そして最重要がmsad-user-account-control-mapperです。これはAD専用のマッパーで、userAccountControlとpwdLastSet属性を読み取り、Keycloak側の状態へ反映します。具体的には、userAccountControlのACCOUNTDISABLEフラグからユーザーの有効/無効を同期し、pwdLastSetが0(パスワード期限切れ)であればUPDATE_PASSWORDの必須アクションを課します。実装上は認証時のMSADエラーコード(532/773/533/775など)も解釈し、期限切れやリセット要求をKeycloakのログインフローに橋渡しします(該当ソース)。AD LDS(旧ADAM)を使う場合は、別途msad-lds-user-account-control-mapperが対応します。
userAccountControlやpwdLastSetの書き込みでLDAPエラーが出るケースは既知の論点なので、本番前にステージングADで必ず一連のシナリオ(無効化・パスワード期限切れ・リセット)を通し検証してください。07パスワードポリシーとKerberos連携
パスワードポリシーの原則は明快で、ポリシーの真実の源はLDAP/AD側です。Keycloakはパスワードを保持せず検証を委譲するため、複雑性や有効期限といったポリシーはAD側で定義され、Keycloakはその結果(認証失敗、期限切れによる変更要求など)を受け取って画面に反映します。KeycloakのRealm側パスワードポリシーは、あくまでKeycloakローカルに保持するパスワード(フェデレーション外のユーザーや、UNSYNCED/WRITABLEで扱うケース)に効くものと整理すると混乱しません。
さらにAD環境ではKerberos連携(SPNEGO)を組み合わせ、社内端末からのシングルサインオンを実現できます。LDAPフェデレーションのプロバイダ設定内でKerberos認証を有効化し、keytabとサービスプリンシパルを用意する構成です。ここは認証フロー設計と密接なので、認証フローの設計とあわせて検討してください。オンプレADからマネージドADへの移行を絡める場合は、マルチアカウント統制や移行方針の整理も並行して進めると手戻りが減ります。
Authorization: Negotiate ヘッダで提示するステートレス方式で、TCP接続の状態には縛られないため、ALBを含むL7ロードバランサでも動作します(HAProxy等もKerberos SSOを公式サポート)。接続に紐づき、接続の多重化・プールで壊れるのはNTLMの方です。Kerberosで本当に効くのはサービスプリンシパル名(SPN)とKeycloakの公開ホスト名(KC_HOSTNAME)の一致で、ここがずれるとチケット検証に失敗します。実務では、TLS終端やホスト名・SPNの整合を単純化したい理由でNLBで素通しする構成を選ぶことはありますが、本質は「ALBだから壊れる」ではなく「SPN/ホスト名を正しく合わせる」ことです。—まとめ
KeycloakのLDAP/ADフェデレーションは、標準機能だけで実務要件の大半を満たせます。ただし成否を分けるのは、(1)編集モードをREAD_ONLYから慎重に選ぶこと、(2)差分同期と全同期を役割分担させ削除反映を全同期に委ねること、(3)objectGUIDを不変IDに据えてフェデレーションIDの二重化を防ぐこと、(4)msad-user-account-control-mapperの挙動を本番前に通し検証すること、の4点に集約されます。いずれも派手ではありませんが、ここを外すと運用で確実に痛みます。要件が固まったら、公式ドキュメントで現行バージョンの設定名を確認しつつ、ステージングADで一通りのシナリオを流してから本番へ進めてください。実案件での構成検討は導入事例もあわせてご覧ください。
—参考(一次情報)
- Keycloak Server Administration Guide — LDAP / User Storage Federation(keycloak.org)
- Red Hat build of Keycloak 26.0 — Server Administration Guide: Using external storage(docs.redhat.com)
- keycloak/keycloak — MSADUserAccountControlStorageMapper.java(GitHub)
- Keycloak API Docs — GroupLDAPStorageMapper Javadoc(keycloak.org)