LDAP(Lightweight Directory Access Protocol)は、ユーザーや端末の情報を階層構造で管理するディレクトリサービスへ、検索や認証のために問い合わせる標準プロトコルです。この記事では、DN・DIT・objectClassといったデータモデルの読み解き方から、bind・searchの操作と検索フィルタの構文、Active Directoryとの正確な関係、LDAPS/StartTLSによる暗号化、自前LDAPとSAML/OIDCの使い分けまで、認証基盤を設計する開発者が実装に落とせる粒度で整理します。後半にはldapsearch・LDIF・ldap3で検証環境を動かす手順まで置きました。社内システムのログインをディレクトリに束ねたい担当者や、既存ADと業務アプリを連携させる技術者が対象です。
まとめ:LDAPはディレクトリへ問い合わせる標準プロトコルという要点と実装勘所
LDAPは「ディレクトリという階層型データベースへアクセスする手順」を定めたプロトコルであり、ディレクトリそのものではありません。ADはディレクトリサービスという製品で、その中身へLDAPという共通言語で問い合わせる、という主従関係になっています。情報はツリー(DIT)で保持し、各エントリはcn=yamada,ou=Sales,dc=example,dc=comのようなDN(識別名)で一意に指し示す形です。
実装の勘所は、認証と暗号化の2点に集約されます。アプリからのユーザー認証は「サービスアカウントでbindしてユーザーのDNを検索し、そのDNで再bindを試みる」流れが定石で、検索フィルタへ入力値を素通しするとLDAPインジェクションを招きます。空パスワードをそのままbindへ渡せば、RFC 4513のいう未認証bindとして通ってしまう点も要注意です。通信は平文の389番ではなくLDAPS(636番)かStartTLSでTLS化するのが前提になります。新規に認証基盤を組むなら、社内アプリはLDAP/ADに束ね、社外向けやSaaS連携はSAML/OIDCのフェデレーションへ委ねる役割分担が現実的です。
LDAPの基本とディレクトリサービス・階層型データモデルの考え方
LDAPを扱う近道は、「プロトコル」と「ディレクトリのデータ構造」を別々に理解することです。この2つを押さえれば、AD連携も認証実装も同じ土台の上で考えられます。
LDAPの定義とディレクトリサービス・「Lightweight」が指す軽量化
LDAPは、ネットワーク上のディレクトリサービスへ問い合わせるためのプロトコルです。ディレクトリサービスとは、ユーザー・グループ・端末・プリンタといった組織内の情報を一元管理する、電話帳のような仕組みです。読み取りが多く更新が少ない特性に合わせて設計されており、リレーショナルデータベースとは用途が分かれます。
名前の「Lightweight(軽量)」は、元となったX.500ディレクトリのアクセスプロトコルDAPが重厚だったことへの対比です。DAPがOSIの通信スタックを前提としたのに対し、LDAPはTCP/IP上で直接動く簡略版として設計されました。現在広く使われるのはLDAPv3で、全体像はRFC 4510のロードマップに、プロトコル本体はRFC 4511に定義があります。標準ポートは平文が389番、TLSで保護するLDAPSが636番です。
DIT・DN・エントリ・objectClassというLDAPのデータモデル
LDAPのデータは、DIT(Directory Information Tree)と呼ばれるツリー構造で保持されます。ツリーの各ノードが1件のエントリで、エントリはメールアドレスや所属といった属性(attribute)の集まりです。ツリーの頂点はドメインを表すdc(domain component)で始まり、組織単位のou(organizational unit)を挟み、末端に個々のユーザーcn(common name)が並びます。
各エントリを一意に指す住所がDN(Distinguished Name)です。末端1階層を表すRDN(Relative Distinguished Name)を根まで連結したものがDNです。DNを文字列で書く規則はRFC 4514が定めており、値に含まれるカンマ・プラス・等号・二重引用符・山括弧や、先頭末尾の空白はバックスラッシュでエスケープします。読点を含む氏名をDNへ入れて検索が壊れる不具合は、この規則を確認せずに実装した際の落とし穴です。どんな属性を持てるかはobjectClassが定義し、inetOrgPersonクラスならmailやtelephoneNumberを持てる、という具合にスキーマで縛られます。
| 用語 | 意味 | 例 |
|---|---|---|
| DIT | エントリを収める階層ツリー全体 | dc=example,dc=com を頂点とする木 |
| エントリ | ツリー上の1ノード(1件の情報) | ある社員1名分のレコード |
| DN | エントリを一意に指す完全な識別名 | cn=yamada,ou=Sales,dc=com |
| RDN | DNのうち末端1階層ぶんの名前 | cn=yamada |
| 属性 | エントリが持つ項目と値 | mail: [email protected] |
| objectClass | 持てる属性を規定するスキーマ | inetOrgPerson |
LDAPとActive Directoryの関係と、自前・クラウドのディレクトリ選択
実務で最も混同されるのが、LDAPとActive Directoryの関係です。ここを製品とプロトコルの主従で整理し、どのディレクトリ実装を選ぶかの判断につなげます。
Active DirectoryはLDAPを実装したディレクトリ製品という主従関係
「LDAPとADのどちらを使うか」という問いの立て方自体が、実は噛み合っていません。LDAPはディレクトリへ話しかけるための共通言語で、ADはその言語を話せるディレクトリサービス製品の一つ、という関係だからです。ADはLDAPインターフェースを備えつつ、Windows環境向けにKerberos認証やグループポリシー(GPO)を独自に足した統合基盤になっています。MicrosoftのActive Directory Domain Servicesの概要も、ディレクトリのデータを保管して利用者と管理者へ提供する役割として説明しています。
そのため、業務アプリからADのユーザー情報を引く場合も、通信そのものはLDAP(既定で389/636番)で行います。「LDAP=プロトコル、AD=それを実装した製品」と押さえれば、両者は比較対象ではなく層が違うと分かります。
OpenLDAP・Active Directory・クラウドディレクトリを選び分ける基準
ディレクトリの実装は、運用主体と対象環境で選び分けます。Linux中心でシンプルな認証基盤を自前で持ちたいならOpenLDAPや389 Directory Server、Windows端末とファイルサーバまで統合管理するならADが出発点です。OpenLDAPを採るなら系列の選択も要ります。公式のダウンロードページは機能リリースと長期サポート(LTS)リリースを別建てで配布しており、2026年9月時点では機能リリースが2.7系、LTSが2.6系という並びです。新機能を追う必要がなければLTS系列に寄せ、設定の書き方は管理者ガイドで系列ごとに確認します。
クラウド前提なら、オンプレADの設計をそのまま持ち込まず、マネージドサービスへ寄せる選択肢があります。Azure/Microsoft 365環境ならMicrosoft Entra ID(旧Azure AD)が候補ですが、Entra IDは従来型LDAPを直接は話さない設計で、既存のLDAP依存アプリを載せるにはEntra Domain Servicesなどの別レイヤと、セキュアLDAPを有効化する手順が必要です。AWS上で従来のADを使いたいならAWS Managed Microsoft ADがパッチ適用や冗長化を肩代わりし、エディションごとのオブジェクト数上限はAWSの管理者ガイドで確認できます。自前運用かマネージドかは、可用性要件と運用工数の天秤で決めます。
LDAPの通信と認証の仕組みをbind・検索・暗号化から捉える実装ポイント
ディレクトリの構造がつかめたら、次はアプリからどう問い合わせ、どう認証するかです。ここは設計を誤るとセキュリティ事故に直結するため、操作と暗号化を具体的な手順で押さえます。
bind・searchとスコープ・LDAP検索フィルタの構文
LDAPの操作は、接続後にまずbind(認証)を行い、search(検索)でエントリを引き、必要に応じてadd/modify/delete/compareで更新し、unbindで切断する流れです。中心はsearchで、検索の起点となるbase DN、探索範囲を決めるスコープ、絞り込み条件のフィルタの3点を指定します。
スコープはRFC 4511の検索要求でbaseObject(起点のみ)・singleLevel(直下の子のみ)・wholeSubtree(配下すべて)の3値と定義され、コマンドラインのbase/one/subが対応します。フィルタはRFC 4515の前置記法で書き、属性と条件を丸括弧で囲みます。「Sales部門のyamada」を探すなら次の形です。
(&(objectClass=inetOrgPerson)(ou=Sales)(cn=yamada))
先頭の&はAND条件、|はOR、!はNOTを表します。この構文は文字列連結で組み立てるため、後述するインジェクション対策の対象になります。
simple bindとSASL・匿名バインドとLDAPインジェクションの注意点
認証にあたるbindには、大きく2方式があります。DNとパスワードを直接送るsimple bindと、Kerberosなどの外部認証機構と連携するSASL bindです。simple bindはパスワードを平文で送るため、TLSでの保護が前提になります。アプリのログイン実装では、サービスアカウントでbindしてユーザーDNをsearchし、そのDNで再度simple bindを試す二段構えが定番です。
ここで3つの落とし穴を避けます。1つは匿名バインド(anonymous bind)で、認証情報なしの接続を許すと、ディレクトリの内部構造や属性を外部から列挙されかねません。用途がなければ無効化します。2つめが未認証bindです。RFC 4513の5.1.2は、DNを指定しつつ長さ0のパスワードを送るbindを未認証の機構と定義し、渡したDNは記録用であって認可に使ってはならないとしています。サーバは既定でunwillingToPerformを返すこと、クライアントは空パスワードの入力を禁じることも同節の要求で、ログインフォームの空欄をそのままbindへ流す実装は認証回避の穴になります。
3つめがLDAPインジェクションです。ユーザー入力を検索フィルタへそのまま連結すると、*や)を注入されて認証回避や情報漏えいを招きます。RFC 4515はNUL・丸括弧・アスタリスク・バックスラッシュをフィルタ値から除外し、バックスラッシュと16進2桁の並びで表す規則です。入力値はこの規則でエスケープするか、パラメータ化に対応したライブラリ経由で組み立てます。ログイン後の権限はRBAC(ロールベースアクセス制御)やABAC(属性ベースアクセス制御)の設計と地続きなので、属性設計と一緒に決めておくと手戻りが減ります。
LDAPS(636番)とStartTLS(389番)による通信の暗号化
LDAPは既定では平文で通信するため、認証情報や属性がそのまま流れます。TLSで保護する方法は2通りです。1つはLDAPS(LDAP over TLS)で、636番へ接続した時点からTLSで暗号化します。もう1つがStartTLSで、389番へ平文で接続した後、コマンドで同一ポート上の通信をTLSへ昇格させます。仕様上の位置づけは対等ではなく、StartTLSはRFC 4511の4.14に拡張操作として規定がある一方、636番のLDAPSは標準化されないまま慣行として定着した方式です。
どちらでも、サーバ証明書の検証を省略しない設定が要点になります。クライアント側で証明書チェックを無効にすると、暗号化していても中間者攻撃を許す状態です。ADは特定の操作(パスワード変更など)がLDAPS必須のため、業務アプリと連携させるなら636番でのTLS接続を初期設計に含めます。MicrosoftはLDAP署名の有効化手順を公開しており、署名を要求する設定にすると平文かつ署名なしのsimple bindは拒否されます。AWS Managed Microsoft ADでもセキュアLDAPは既定で無効で、証明書を登録して明示的に有効化する運用です。
ldapsearchとLDIF・ldap3で認証をローカルに再現する手順
仕様を読んだだけでは、フィルタの効き方も証明書検証の失敗も体感できません。ここでは検証用のディレクトリに対し、コマンドで引き、エントリを入れ、アプリから認証するまでを実行できる形で置きます。手元にサーバがなければ、OpenLDAPのコンテナを1つ立てれば同じ手順をなぞれます。
ldapsearchでbindと検索スコープの挙動を手元で確かめる
OpenLDAP付属のldapsearchは、アプリを書く前に接続とフィルタを検証する道具です。オプションの一覧は公式のマニュアルページが一次情報です。-xでsimple bind、-DでbindするDN、-bで検索の起点、-sでスコープを指定します。同じフィルタでスコープだけbase・one・subと変えると、ヒット件数の差から探索範囲の意味がつかめます。
ldapsearch -x -H ldap://ldap.example.com \
-D "cn=svc,ou=Apps,dc=example,dc=com" -W \
-b "dc=example,dc=com" -s sub \
"(&(objectClass=inetOrgPerson)(uid=yamada))" dn mail
# StartTLSを必須にして同じ検索を流す(失敗したら接続を打ち切る)
ldapsearch -x -ZZ -H ldap://ldap.example.com \
-b "dc=example,dc=com" -s one "(objectClass=organizationalUnit)" dn
2つめの例の-ZZは、StartTLSに失敗したら処理を打ち切る指定です。証明書の検証で落ちるなら、CA証明書の配置かホスト名の不一致を疑います。ここで通らない設定は、アプリからも通りません。
LDIFでテスト用エントリを投入しobjectClassの縛りを確かめる
検証データの投入には、RFC 2849が定めるLDIF(LDAP Data Interchange Format)というテキスト形式を使います。1行目にDN、続けて属性を並べるだけの書式で、スキーマ違反はその場でエラーです。必須属性を1つ落として流し、返るメッセージを見ておくと、objectClassが縛りとして働く様子が分かります。
dn: uid=yamada,ou=Sales,dc=example,dc=com
objectClass: inetOrgPerson
cn: Taro Yamada
sn: Yamada
uid: yamada
mail: [email protected]
# 投入コマンド(sn を消して流すと objectClassViolation が返る)
ldapadd -x -D "cn=admin,dc=example,dc=com" -W -f user.ldif
投入したら、先ほどのldapsearchで同じエントリを引けるか確かめます。DNの綴りとou階層が一致しないと引けないため、DITとDNの対応をここで押さえておくと後で迷いません。
ldap3で二段bindの認証を実装しフィルタをエスケープする
アプリ側の実装例として、Pythonのldap3で二段構えの認証を書きます。要点は3つで、サービスアカウントでDNを引くこと、入力値をescape_filter_charsに通すこと、空パスワードを未認証bindへ流さないよう先に弾くことです。TLSはTlsオブジェクトで証明書検証を必須にします。
import os, ssl
from ldap3 import Server, Connection, Tls, SUBTREE
from ldap3.utils.conv import escape_filter_chars
tls = Tls(validate=ssl.CERT_REQUIRED, ca_certs_file="ca.pem")
server = Server("ldap.example.com", port=636, use_ssl=True, tls=tls)
BASE = "dc=example,dc=com"
def authenticate(uid, password):
if not password: # 空文字は未認証bindになるため先に拒否する
return False
svc = Connection(server, "cn=svc,ou=Apps,dc=example,dc=com",
os.environ["SVC_PASSWORD"], auto_bind=True)
flt = "(&(objectClass=inetOrgPerson)(uid=%s))" % escape_filter_chars(uid)
svc.search(BASE, flt, search_scope=SUBTREE, attributes=["cn"])
if len(svc.entries) != 1: # 0件も複数件も認証させない
return False
return Connection(server, svc.entries[0].entry_dn, password).bind()
検索結果が1件でなければ落とすのは、同じuidが複数エントリにあるときに別人でbindが通るのを防ぐためです。パスワード照合をbindの成否に委ねているのも意図的で、ハッシュ方式の違いをアプリが知らずに済みます。保管方式そのものを設計するなら、ハッシュ化の考え方も押さえておきます。
LDAPを採用する場面と、フェデレーションへ寄せるべき場面の判断
仕組みが出そろったところで、採用判断を条件で言い切ります。何でもLDAPに寄せる設計は、社外連携やSaaS時代の要件で破綻しやすく、役割で線を引くのが現実解です。
LDAP/ADを認証基盤に採用する条件と、向いているシステムの特徴
LDAPを中核に据えるのが妥当なのは、境界がはっきりした組織内システムです。社員向けの社内アプリ、ファイルサーバ、グループウェアなど、利用者が自組織に閉じ、端末やアカウントを一元管理したい場面では、LDAP/ADへの集約が効きます。1か所のディレクトリを更新すれば全システムへ反映され、退職者の無効化も一元的に回せます。
既存でADを運用している組織なら、新規の業務アプリもまずADのLDAPインターフェースで認証を通すのが自然です。多要素認証を足したい場合も、ディレクトリ認証の後段に多要素認証(MFA)を重ねる構成で無理なく拡張できます。「利用者が内部に閉じ、端末込みで統制したい」ならLDAPは今も第一候補です。
LDAPに閉じず、SAML/OIDCへ橋渡しすべき場面と失敗パターン
逆に、LDAPだけで押し切ると失敗する場面もはっきりしています。外部のSaaSや社外パートナーへのログインを、LDAPを社外公開して実現しようとする設計です。LDAPはもともと境界内での利用を想定したプロトコルで、インターネット越しに直接さらすとインジェクションや認証情報流出のリスク面が大きく、実務では採るべきではありません。ここはSAMLやOIDC(OpenID Connect)といったフェデレーション規格の領分です。
現実的な設計は、社内のLDAP/ADを唯一のアカウント源(信頼の起点)に置きつつ、外向きの認証はIdPを立ててSAML/OIDCで各SaaSへ渡す二段構えです。ディレクトリが「誰か」を、フェデレーションが「外部サービスへどう入るか」を担います。複数SaaSを1回のログインでまたぐならシングルサインオン(SSO)の実現方式を、認証手段の全体像から選び直すなら認証・ID管理の整理を先に読むと、LDAPへどこまで担わせるかの線が引けます。導入可否の判断は、二段階認証の観点も含めて整理しておくと迷いません。こうしたLDAP/ADとSaaS連携をまたぐ社内の認証設計と実装は、認証基盤・ID管理システム開発としてディレクトリ連携ごと受託しています。既存ADをどこまで使うかの線引きから、ご相談ください。
よくある質問
LDAPの設計・実装でよく挙がる疑問を、開発者の視点で簡潔にまとめます。
LDAPとActive Directoryは何が違うのですか?
層が異なります。LDAPはディレクトリへ問い合わせるためのプロトコル(共通言語)で、Active Directoryはそのプロトコルを話せるディレクトリサービス製品の一つです。つまり「どちらか」ではなく、ADの中身へLDAPで問い合わせる、という主従の関係になります。
LDAPで使うポート389と636の違いは何ですか?
暗号化の有無です。389番は平文のLDAP、636番はTLSで暗号化するLDAPS(LDAP over TLS)の標準ポートです。389番のまま接続後にStartTLSコマンドでTLSへ昇格させる方法もあり、こちらはRFC 4511の4.14に規定があります。本番では636番のLDAPSかStartTLSを前提にし、サーバ証明書の検証も有効にします。
LDAPでユーザー認証はどう実装するのですか?
bindという認証操作を使います。定番は「サービスアカウントで一度bindし、入力されたユーザー名からDNをsearchで特定、そのDNとパスワードで再度bindを試みて成功可否を判定する」二段構えです。入力値を検索フィルタへ直接連結するとLDAPインジェクションを招くため、特殊文字のエスケープやライブラリのパラメータ化を通します。空パスワードを弾く処理と、検索結果が1件のときだけ認証を通す条件も入れてください。
OpenLDAPとActive Directoryはどちらを選ぶべきですか?
環境と管理対象で選び分けるのが基本です。Linux中心でユーザー認証のディレクトリを軽量に自前運用したいならOpenLDAP、Windows端末やファイルサーバまで含めて統合管理したいならActive Directoryが向きます。OpenLDAPを採るなら、機能リリース系列とLTS系列のどちらに乗るかも決めておきます。クラウド前提なら、マネージドADやIDaaSのMicrosoft Entra IDへ寄せる選択肢も検討対象です。
LDAPとSAML/OIDCはどう使い分けますか?
対象範囲で使い分けるのが基本です。LDAPは境界内のディレクトリ照会・認証に向き、社内システムのアカウント一元管理に使います。社外のSaaSやパートナー間のログインは、LDAPを外部公開せず、SAMLやOIDCのフェデレーションに任せます。社内LDAP/ADをアカウントの起点に置き、外向きはIdP経由でSAML/OIDCへ渡す二段構えが、実務での標準的な組み合わせです。
関連記事
- Microsoft Entra ID(旧Azure AD)とは?Active Directoryとの違い・機能・料金を解説:LDAP依存アプリをクラウドへ移す際の受け皿です。
- AWS Managed Microsoft ADとは?料金・エディションの違い:ADのLDAP環境をAWS上でマネージド運用する選択肢です。
- SAMLとは?認証フロー・IdP/SPの仕組みと使い分けを実装視点で解説:LDAPの外へ出す社外SaaS連携の規格を扱います。
- OIDC(OpenID Connect)とは?仕組み・OAuthとの違いをわかりやすく解説:IdPが発行するIDトークンの認証層です。
- シングルサインオン(SSO)とは?4つの実現方式とIdP選定を実装手順で解説:束ねたアカウントを複数サービスへ広げる段の設計です。