KeycloakのLDAP連携は、管理コンソールの「User federation」にLDAPプロバイダーを1つ足す作業です。社内のActive Directoryのアカウントでそのままログインでき、パスワードの照合はAD側で行われます。本記事は2026年11月5日時点の最新版Keycloak 26.8.1を前提に、ADをつなぐときの接続方式、kcadm.shでの登録コード、グループと無効化の取り込み、同期の周期、障害時の切り分けまでを順に解説します。OpenLDAPを読み取り専用でつなぐ基本形は、ID管理のOSSを役割で選ぶ記事のUser Federationの章で扱いました。
まとめ:KeycloakのLDAP連携はLDAPS・読み取り専用・ページングで組む
ADをつなぐなら、接続URLはldaps://にし、編集モードはREAD_ONLY、Paginationは有効にします。Windows Server 2025で新しく作ったドメインでは、暗号化していない接続のsimple bindをドメインコントローラーが拒否するため、ldap://のままでは接続テストから先に進めません。ADが返す件数は既定で1回1,000件までなので、ページングを切ると社員の一部しか同期されない事故になります。
グループはgroup-ldap-mapperで写し、入れ子のグループを使う組織だけ再帰取得を選びます。退職者の無効化は、vendorをADにすると自動で作られるMSADのマッパーがuserAccountControlから反映します。オンプレのADが正本で、複数の社内アプリに同じログインを配る構成ならLDAP連携が素直です。ADをEntra IDへ同期済みでアプリもクラウドにあるなら、LDAPはつながずにEntra IDを外部IdPにします。
KeycloakのLDAP連携で決める保存方式・編集モードと認証の流れ
LDAP連携の設定項目は多いものの、後から変えられないのは保存方式と編集モードの2つだけです。Keycloakそのものの役割はKeycloakとは?Oktaとの違いと連携手順で、LDAPの用語と仕組みはLDAPとは?仕組み・Active Directoryとの違いで整理しています。
利用者を取り込みパスワードだけADで照合するUser Federationの仕組み
Import UsersをONにすると、KeycloakはLDAPの利用者を自分のデータベースに写します。26.8.1の管理ガイドのLDAPの節は、パスワードは決して取り込まず、照合は常にLDAPサーバー側で行うと書いています。取り込みのタイミングは、初回ログインか管理画面での検索時で、対象は1人ずつです。全員を先に入れたいときは同期を使います。
取り込んだ利用者はKeycloakのDBに行が増えるので、DBのバックアップ対象にも入ります。DBの設定とバックアップはKeycloakのデータベース設定と使い方を参照してください。
Import UsersとEdit Modeを作成時に決める理由と3つのモードの違い
| Edit Mode | Keycloakでの変更 | 向く構成 |
|---|---|---|
| READ_ONLY | 氏名・メール・パスワードとも不可 | ADが正本 |
| WRITABLE | ADへ書き戻す | Keycloakで登録も受ける |
| UNSYNCED | KeycloakのDBだけに保存 | ADに書けないが一部を変えたい |
管理ガイドは、プロバイダー作成時にVendor・Edit Mode・Import Usersの組み合わせから初期マッパーが作られ、後でモードを変えてもマッパーの設定は変わらないと注意しています。人事の入退社をADで処理している会社なら、READ_ONLYを選んでKeycloakから氏名やパスワードを変えられないようにします。台帳が2か所になる構成を避けるためです。
ADをKeycloakに登録する前に確かめる署名の要件と証明書・接続アカウント
ADとの連携で最初につまずくのは、Keycloakの設定より手前の接続です。登録前に、ドメインコントローラーの署名の設定、LDAPSの証明書、Keycloakが使うアカウントの3点を確かめます。
Windows Server 2025新規ADで平文simple bindを拒否する条件
Keycloakは、bindDNとパスワードを送るsimple bindでADに接続します。MicrosoftのLDAP署名の概要(2026年10月2日更新)によると、Windows Server 2025以降は新しいAD環境でLDAP署名を既定で必須にします。署名を強制したドメインコントローラーでは、暗号化されていない接続でのsimple bindは拒否の対象です。
同じページは、2022以前からのアップグレードでは既存のポリシーが引き継がれるとも書いています。つまり、既存ドメインではldap://で通っていた設定が、2025で作り直したドメインでは通りません。LDAP署名はsimple bindを守らないので、Keycloakではldaps://(636番)かStartTLSを使うのが前提です。診断ログの「16 LDAP Interface Events」を2にすると、ドメインコントローラーのイベントID 2889に、平文で接続してきたクライアントのIPが記録されます。
LDAPSのCA証明書をKeycloakのtruststore-pathsで信頼する設定
ADの証明書が社内CAの発行なら、KeycloakのJavaはそのままでは信頼しません。Configuring trusted certificatesのとおり、PEMかPKCS12の証明書をconf/truststoresに置くか、起動オプションで渡します。
# ドメインコントローラーが提示する証明書チェーンを確かめる
openssl s_client -connect dc01.corp.example.local:636 -showcerts < /dev/null
# 社内ルートCAの証明書(PEM)を Keycloak に信頼させる(どちらか一方)
cp corp-root-ca.pem /opt/keycloak/conf/truststores/
bin/kc.sh start --truststore-paths=/etc/pki/keycloak/corp-root-ca.pem
証明書のホスト名の検証は既定のDEFAULTのまま使い、本番でANYにしてはいけないと同じページにあります。古い解説で見かける「Use Truststore SPI」をldapsOnlyにする設定は、26.8.1の管理ガイドでは非推奨で、通常はAlwaysのままにすると書かれています。コンテナで動かす場合に証明書をどこへマウントするかは、Keycloak Dockerの本番構成で確認できる内容です。
接続用アカウントの権限と複数ドメインコントローラーの指定方法
bindDNには、ドメイン管理者ではなく読み取りだけの専用アカウントを使います。READ_ONLYなら書き込み権限は要りません。接続URLにはドメインコントローラーを空白区切りで複数書けます。
- 区切りは空白だけ。カンマで区切ると接続エラーか、先頭のURLが黙って捨てられる
- 左から順に試す方式で、負荷分散はしない
- 到達できないサーバーごとにConnection Timeout(既定5,000ミリ秒)を待ってから次へ移る
- 全サーバーが同じディレクトリの複製で、
objectGUIDが一致していること
同じドメインのドメインコントローラー同士なら最後の条件は満たします。別々に立てたLDAPに同じデータを入れた構成では識別子が食い違い、切り替わった瞬間に同期と認証が失敗すると管理ガイドは書いています。
kcadm.shでActive DirectoryのLDAPプロバイダーを作成するコード
管理コンソールでも同じ設定ができますが、検証環境と本番に同じ値を入れるなら、同梱の管理CLIkcadm.shで組むほうが再現できます。以下、レルムをcorp、ADのドメインをcorp.example.localとします。
testLDAPConnectionで接続と認証を登録前に確かめる2つのコマンド
プロバイダーを作る前に、接続と認証だけを試します。Server Administration Guideの管理CLIの章にあるtestLDAPConnectionを使います。
# 管理 CLI にログインする(パスワードは対話入力)
kcadm.sh config credentials --server https://auth.example.com --realm master --user admin
AD_URL='ldaps://dc01.corp.example.local:636'
AD_BIND='CN=svc-keycloak,OU=Service,DC=corp,DC=example,DC=local'
# 1. TCP と TLS の接続だけを試す
kcadm.sh create testLDAPConnection -r corp -s action=testConnection \
-s connectionUrl="$AD_URL" -s bindDn="$AD_BIND" \
-s bindCredential="$AD_BIND_PW" -s useTruststoreSpi=always
# 2. 接続用アカウントで bind できるかを試す
kcadm.sh create testLDAPConnection -r corp -s action=testAuthentication \
-s connectionUrl="$AD_URL" -s bindDn="$AD_BIND" \
-s bindCredential="$AD_BIND_PW" -s useTruststoreSpi=always
1が失敗するなら証明書かファイアウォール、1が通って2が失敗するならbindDNかパスワードの誤りです。ldap://で2だけが失敗する場合は、前の章の署名の要件を疑います。
vendor=ad:sAMAccountNameとobjectGUIDの設定
設定キーの名前は、26.8.1のLDAPConstants.javaと管理ガイドの作成例に合わせています。
# parentId に入れるレルムの id を取り出す
REALM_ID=$(kcadm.sh get realms/corp --fields id --format csv --noquotes)
kcadm.sh create components -r corp -i \
-s name=corp-ad -s providerId=ldap \
-s providerType=org.keycloak.storage.UserStorageProvider \
-s parentId="$REALM_ID" \
-s 'config.vendor=["ad"]' \
-s 'config.importEnabled=["true"]' \
-s 'config.editMode=["READ_ONLY"]' \
-s "config.connectionUrl=[\"$AD_URL ldaps://dc02.corp.example.local:636\"]" \
-s 'config.usersDn=["OU=Staff,DC=corp,DC=example,DC=local"]' \
-s 'config.searchScope=["2"]' \
-s 'config.usernameLDAPAttribute=["sAMAccountName"]' \
-s 'config.rdnLDAPAttribute=["cn"]' \
-s 'config.uuidLDAPAttribute=["objectGUID"]' \
-s 'config.userObjectClasses=["person, organizationalPerson, user"]' \
-s 'config.authType=["simple"]' \
-s "config.bindDn=[\"$AD_BIND\"]" \
-s "config.bindCredential=[\"$AD_BIND_PW\"]" \
-s 'config.pagination=["true"]' \
-s 'config.syncRegistrations=["false"]' \
-s 'config.fullSyncPeriod=["-1"]' \
-s 'config.changedSyncPeriod=["3600"]'
-iで表示されるIDは、後のマッパーと同期で使うので控えます。searchScopeの2はサブツリーで、OU=Staffの下の部署ごとのOUまで探します。ユーザー名はWindowsのログオン名と同じsAMAccountNameにしました。メールアドレス形式で入らせたいならuserPrincipalNameも選べます。
ADの検索上限MaxPageSize 1,000件とPaginationを有効にする理由
MicrosoftのLDAPポリシーの上限の解説によると、ADのMaxPageSizeは既定で1,000です。1回の検索で返す件数がそこで止まるので、社員が1,000人を超える会社でページングを使わないと、全件同期で一部しか取り込まれません。
同じ記事は、ポリシーの値を上げるよりページ付きの検索に対応するよう勧めています。Keycloak側はpaginationをtrueにすれば足ります。ADのポリシーには触らないでください。
グループマッパーとMSADマッパーでADのグループと無効化を写す設定
利用者を取り込んだだけでは、ADのグループもアカウントの無効化もKeycloakに届きません。マッパーを足して写します。
group-ldap-mapperでADのセキュリティグループを取り込むコマンド
ロールに使うグループだけを1つのOUにまとめ、そのOUをgroups.dnに指定します。ドメイン全体のグループを写すと、Keycloakのグループ一覧が数千件で埋まります。
LDAP_ID='前の手順で表示された id'
kcadm.sh create components -r corp -i \
-s name=ad-groups -s providerId=group-ldap-mapper \
-s providerType=org.keycloak.storage.ldap.mappers.LDAPStorageMapper \
-s parentId="$LDAP_ID" \
-s 'config."groups.dn"=["OU=KeycloakGroups,DC=corp,DC=example,DC=local"]' \
-s 'config."group.name.ldap.attribute"=["cn"]' \
-s 'config."group.object.classes"=["group"]' \
-s 'config."preserve.group.inheritance"=["false"]' \
-s 'config."membership.ldap.attribute"=["member"]' \
-s 'config."membership.attribute.type"=["DN"]' \
-s 'config.mode=["READ_ONLY"]' \
-s 'config."user.roles.retrieve.strategy"=["LOAD_GROUPS_BY_MEMBER_ATTRIBUTE_RECURSIVELY"]'
# 表示されたマッパーの id で、AD のグループを Keycloak へ取り込む
kcadm.sh create "user-storage/$LDAP_ID/mappers/$MAPPER_ID/sync?direction=fedToKeycloak" -r corp
preserve.group.inheritanceの既定はtrueです。GroupLDAPStorageMapperFactory.javaの説明文は、1つのグループが複数の親を持つ構造では同期が失敗しうると書いています。ADでは珍しくない構造なので、ここではfalseにして平らに取り込みました。modeのREAD_ONLYは、ADとKeycloakのDBの所属を合わせて読み、Keycloakでの追加はADへ書かない指定です。
入れ子のグループを拾う3つの取得方法の違いと再帰取得の使いどころ
| 取得方法 | 所属の調べ方 | 入れ子 |
|---|---|---|
| ①member検索(既定) | memberに本人を含むグループを検索 | 拾わない |
| ②memberOf参照 | 本人のmemberOfを読む | 拾わない |
| ③再帰検索(AD限定) | 入れ子をたどる拡張で検索 | 拾う |
設定値は、①がLOAD_GROUPS_BY_MEMBER_ATTRIBUTE、②がGET_GROUPS_FROM_USER_MEMBEROF_ATTRIBUTE、③がLOAD_GROUPS_BY_MEMBER_ATTRIBUTE_RECURSIVELYです。③はADだけで選べる方法で、LDAP_MATCHING_RULE_IN_CHAIN(OID 1.2.840.113556.1.4.1941)の拡張を使います。「営業部」グループの中に「東京営業課」を入れる運用なら、3つ目を選ばないと課のメンバーに営業部のロールが付きません。入れ子を使っていない組織は、既定のままで構いません。
MSADのマッパーでuserAccountControlの514を無効化として反映する
vendorをadにして作ると、初期マッパーとしてMSAD account controls(msad-user-account-control-mapper)が自動で作られます。管理ガイドによると、userAccountControlが514(無効なアカウント)ならKeycloakの利用者も無効になります。pwdLastSetが0の場合は、次のログインでパスワード変更を求める動作です。
ADで退職者のアカウントを無効にする運用なら、このマッパーを消さないでください。消すと、ADで止めた社員もKeycloak上は有効のまま表示され、管理画面で区別できません。パスワードの照合はADで失敗しても、ログイン済みのセッションは残ります。退職の当日は、Keycloakの管理画面で該当者のセッションも削除します。
同期の周期とトラブル時の切り分け:全件同期・差分同期・TRACEログ
Import UsersをONにした構成では、同期の周期で反映の遅れが決まります。障害時は、Keycloakが実際にADへ送った検索条件をログで見るのが近道です。
初回の全件同期と差分同期をその場で実行するコマンドと周期の目安
管理ガイドは、作成直後に全件同期を1回実行し、その後は変更分の定期同期にする方法を勧めています。差分同期は、LDAPのcreateTimestampとmodifyTimestampで検索できることが前提です。
# 初回だけ全件を取り込む
kcadm.sh create "user-storage/$LDAP_ID/sync?action=triggerFullSync" -r corp
# 定期実行を待たずに、変更分だけをその場で取り込む
kcadm.sh create "user-storage/$LDAP_ID/sync?action=triggerChangedUsersSync" -r corp
定期実行の周期は、前の章の作成コマンドでfullSyncPeriodを-1(無効)、changedSyncPeriodを3600にしました。単位は秒で、変更分を1時間ごとに取り込む設定です。社員が数百人規模なら、全件同期を1日1回(86400)足しておくと、差分で拾えなかった変更の保険になります。
ADで削除した利用者が残る仕組みとRemove invalid usersの設定
差分同期は、前回以降に作られたか更新された利用者を作成・更新するだけです。ADからアカウントを削除しても、取り込み済みの行はKeycloakのDBに残ります。管理ガイドの説明では、「Remove invalid users during searches」がOFFなら、LDAPに無くなった利用者は読み取り専用・無効の状態で残ります。
ONにすると、検索のときにLDAPに見つからない利用者をDBから消します。ただしキャッシュに載っていない利用者に限られます。退職の処理は削除ではなく無効化を先に行い、MSADのマッパーで止めてから削除する順番が安全です。
org.keycloak.storage.ldapのTRACEログで検索条件を確認
同期件数が足りない、特定の社員だけログインできないといった症状は、ログでKeycloakの検索条件を見ると原因が分かります。管理ガイドはorg.keycloak.storage.ldapのカテゴリをTRACEにする方法を案内しており、指定方法はConfiguring loggingのとおりです。
# LDAP 連携のカテゴリだけ TRACE にして起動する
bin/kc.sh start --log-level="INFO,org.keycloak.storage.ldap:trace"
# コンテナなら環境変数で同じ指定をする
KC_LOG_LEVEL='INFO,org.keycloak.storage.ldap:trace'
TRACEではADへの全クエリとパラメーターが出ます。プロバイダー作成時にINFOで出るCreating new LDAP Storeの行には設定の全体が載るので、まずここでusersDnと接続URLを確かめます。プロバイダーの「Connection trace」はLDAPとの送受信データをすべて出力するので、本番では有効にしません。
KeycloakのLDAP連携を採用する条件とEntra IDやAPI同期を選ぶ場面
LDAP連携は、ADとKeycloakの間に常時の接続を張る構成です。ADに届かないネットワークにKeycloakを置くなら、成り立ちません。
オンプレのADが正本で複数アプリに同じログインを配る構成の判断基準
LDAP連携を選ぶのは、社員の台帳がオンプレのADにあり、KeycloakとADが同じ社内ネットワークかVPNでつながる場合です。WindowsのログオンIDとパスワードがそのまま業務アプリで使えるので、利用者への周知がほとんど要りません。OIDCとSAMLのアプリが混在していても、ロールはKeycloak側で1か所にまとめられます。
ADの構成の見直しからKeycloakの導入、既存システムのログインの付け替えまでをまとめて任せたい場合は、一創の認証基盤・ID管理システム開発で支援しています。
Entra ID同期済みの組織やAD以外が正本の場合にLDAPをつながない条件
ADをEntra IDへ同期済みで、アプリもクラウドにあるなら、LDAPはつなぎません。KeycloakからADへの経路を開けるより、Entra IDを外部IdPにするSAMLのブローカー構成のほうが、多要素認証や条件付きアクセスもEntra ID側の設定がそのまま効きます。
台帳がADではなく人事システムや会員DBにある場合も、LDAP連携は選びません。Keycloak APIの使い方で解説したAdmin REST APIで利用者を作る同期のほうが、間にLDAPを1台立てる構成より部品が減ります。
KeycloakとActive DirectoryのLDAP連携でよく受ける質問と回答
KeycloakのLDAP連携を設定する担当者から出やすい質問をまとめました。
Import UsersをOFFにすればKeycloakのDBに社員の情報は残りませんか?
OFFにすると、利用者の情報は毎回LDAPから読み、KeycloakのDBに写しません。ただし管理ガイドによると、LDAPに写していない属性は保存できず、LDAPの属性に対応していないenabledなどは管理画面から変えられません。ロールの付与もLDAPのマッパー経由に限られます。ログインのたびにLDAPを読むので、ADが止まるとログインも止まる点はONの場合と同じです。
KeycloakからADのパスワードを変更させることはできますか?
Edit ModeをWRITABLEにすれば、アカウント画面で変えたパスワードをADへ書き戻せます。ADはパスワードの変更を暗号化された接続でしか受け付けないので、接続はldaps://が前提です。MSADのマッパーでパスワードポリシーのヒントを有効にすると、履歴や最小有効期間といったADのパスワードポリシーも変更時に適用されます。ADを正本にするならREAD_ONLYのまま、変更はWindows側で行う運用が単純です。
OpenLDAPとつなぐ場合はActive Directoryの設定と何が違いますか?
vendorをotherにし、ユーザー名をuid、一意の識別子をentryUUID、オブジェクトクラスをinetOrgPersonにします。グループのオブジェクトクラスはgroupOfNamesで、入れ子の再帰取得とMSADのマッパーは使えません。管理ガイドは、OpenLDAPではパスワード変更時にPassword Modify拡張操作を有効にしないと平文で保存されると注意しています。手順の全体はID管理のOSSを役割で選ぶ記事にあります。
AWS Managed Microsoft ADにもKeycloakからLDAPで接続できますか?
接続先がLDAPとLDAPSを話すADであれば、Keycloak側の設定は本記事と同じです。違いは、ドメインの管理者権限が渡されないことと、LDAPSの有効化をAWSのマネージドサービスの手順に沿って行うことです。サービスの種類とAD ConnectorやSimple ADとの違いはAWS Managed Microsoft ADとはで整理しています。
LDAP連携を入れたKeycloakの更新で気をつけることはありますか?
LDAP連携の設定はKeycloakのDBに保存されるので、版を上げても作り直しは要りません。更新の前後では、接続テストと1人分のログイン、グループの所属が取れているかを確かめます。Keycloakの修正版は頻繁に出ており、26.8系の最新は2026年10月13日公開の26.8.1です。更新の判断と手順はKeycloakの脆弱性対応の手順にまとめました。
関連記事
- ID管理のOSSを役割で選ぶ:Keycloak・midPoint・OpenLDAPの構成と連携手順:OpenLDAPをUser Federationで読み取り専用につなぐ基本の手順です。
- Keycloakとは?Oktaとの違いと連携手順|Auth0・Cognito比較で導入を判断【2026年10月】:Keycloakの機能と他製品との違いを確認できます。
- LDAPとは?仕組み・Active Directoryとの違いと認証実装をコード付きで解説:DNやbindなど、設定に出てくる用語の基礎です。
- Keycloak SAML設定:Entra IDを外部IdPにする手順と属性マッパー:LDAPを使わずEntra IDでログインさせる構成です。
- Keycloak Dockerの本番構成:Composeでの起動とリバースプロキシ・ヘルスチェックの設定:証明書の配置と起動オプションの渡し方です。