マイクロソフト系技術情報 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。

目次

概要

Lightweight Directory Access Protocol(以下、LDAPと略す)は、X.500に基づいたディレクトリ サービス上のデータを参照・操作(追加・更新・削除)するためのプロトコルであるが、LDAPを使用するには、ディレクトリ サービス、LDAPの構文の知識が必要になる。そこで本ページでは、LDAPを使用して、ディレクトリ サーバへアクセスするプログラムを作成する上で最低限必要となるディレクトリ サービス、LDAP、LDAPの構文について説明した上で、.NET Frameworkから利用可能なAPIライブラリであるADSI(Active Directory Services Interfaces) を使用し、LDAPを使用して、ディレクトリ・サーバへアクセスするプログラムについて説明する。

LDAPの基本事項

LDAPとは?

LDAPの動作

LDAPを実装した、ディレクトリ サービス(LDAPサーバ)は、
『DIB(Directory Information Base)』と呼ばれるデータベースを保有している。

LDAPシステムの概要図

LDAPの機能

LDAPクライアント・サーバシステムの機能を簡単に説明する。

LDAPのAPIライブラリ

元々LDAPはAPI定義も含めた標準仕様であるため、環境を用意しやすく、さまざまなAPIライブラリが存在している。
これらのAPIを利用すれば、LDAPのプロトコルレベルの仕様を知らなくとも簡単に情報の検索や変更処理が実装できる。

以下は、その中の主なAPIである。

LDAPを実装したディレクトリ サービス

LDAPサーバ ソフトウェア

LDAPサーバ ソフトウェアには、以下のものがある。

Active Directory、NTディレクトリ サービス

Red Hat Directory Server

無償である「Fedora Directory Server」の商用版。
「Netscape Directory Server」のテクノロジをベースとしている。

Sun Java System Directory Server

Open LDAP

Hitachi Directory Server

ディレクトリ サービス(LDAPサーバ)の特徴

項番項目ディレクトリ サービス(LDAPサーバ)RDBMS
1使用システム検索・認証システム業務システム(例:流通・会計システム)
2用途格納データの検索格納データの参照・更新
3データ形式木構造テーブル(表)
4格納データユーザ情報、コンピュータリソース業務データ(例:商品情報、顧客情報)
5スキーマ定義標準が存在(スキーマ、プロトコル、API)スキーマはユーザが決定
6トランザクション単純な書き換えACID機能を実装

ディレクトリ サービス(LDAPサーバ)のデータ構造

ディレクトリ サービス(LDAPサーバ)では、

DIT(Directory Information Tree)

『DIT』のデータ構造に関する詳細は、本ページ:「ディレクトリ・サービスの基本事項」で詳しく説明する。

DIT(Directory Information Tree)

以下に、LDAPサーバの『DIT』の例を示す。

DIT(Directory Information Tree)

本章では、LDAPにおける『DIT』形式でデータの

などについて説明する。

DIT上のエントリを特定する

相対識別名と識別名

エントリと相対識別名)

識別名

エントリと識別名)

『識別名』は、上位の『エントリ』の『相対識別名』を「,」を使って全て並べて作成する。
例えば、図の3つの『A』エントリの『識別名』はそれぞれ次のようになる。

これにより、『DIT』上の『エントリ』を特定することができる。
これで『エントリ』を特定できない場合は、エントリを区別するために、親エントリを追加する必要がある。
また、兄弟で同じ『相対識別名』にすると『エントリ』を区別できなくなるため兄弟間では同じ『相対識別名』をつけてはいけない。

エントリのデータ構造

ディレクトリという単語には「人名簿」・「住所録」という意味がある。実際、ディレクトリ サービスは、「人名簿」・「住所録」などを基に案内をする。通常、「人名簿」・「住所録」といえば、50音順で構成されている「個人情報」の一覧表を持っている。各個人情報は「あ行」・「か行」のような行毎に分類され、各「個人情報」が『エントリ』になる。

LDAPに於ける『DIT』では、50音順の一覧ではなく、木構造によって「個人情報」を分類する。

木構造の名簿)

LDAPに於ける『DIT』上の『エントリ』の各項目を『属性』と呼ぶ。木構造では、共通の『属性』が親の『エントリ』に抜き出される特徴があり、各『エントリ』に登録する情報を集約すると、階層構造をとれなくなる点に注意する。例えば、上記のエントリに、「姓情報」という属性を追加すると、親のエントリに「姓情報」を抜き出した、階層構造が取れなくなる。

属性と属性型・属性値

『エントリ』を構成する『属性』は『属性型』(属性の種類)と『属性値』(属性の内容)から構成される。また、『属性』は、次のように記述する。

例えば、『属性』「生年月日」は、

から構成され、以下のように記述する。

名前付け属性

『エントリ』の『相対識別名』を表の外に書いた場合、『相対識別名』を保持するための概念が、『エントリ』の『属性』の他に新たに必要となってしまう。このため、LDAPでは『相対識別名』を1つの『属性』として管理している。この『相対識別名』を『属性値』として持つ『属性』を、『名前付け属性』という。

名前付け属性)

属性と相対識別名の表記法方の違い

『相対識別名』から『識別名』を生成する場合、『属性型』の「:」と『属性値』の「:」を区別するため、『相対識別名』は、次のように記述する。

例えば、「太郎」の『識別名』を『属性』の表記方法で記述すると次のようになる。

これに、『識別名』という『属性』を明記すると以下のようになる。

この表記では、『属性型』の「:」と、『属性値』の「:」を区別し難い。
このため、『識別名』の『属性値』の要素である『相対識別名』を規定の記述方法で記述する。

これにより、『識別名』の『属性値』の要素である『相対識別名』の『属性型』が解かり易くなる。

objectclass

『エントリ』の中に自由に情報を書き込めれば、融通がきく側面もあるが、あまり自由に使用されると、脈絡のない見づらい情報になる。このため、『エントリ』が保持できる『属性型』の一覧を保持する『属性』を『エントリ』内に埋め込む。これによって各『エントリ』が保持する『属性型』を定義できる。なお、LDAPでは、『エントリ』が保持できる『属性型』の一覧を保持する『属性』の『属性型』『objectClass』という。

先に示した、個人情報『エントリ』の例では、『属性』として、 『属性型』=「objectClass」、『属性値』=「個人情報」を埋め込む。

個人情報エントリのobjectClass)

同様に、姓情報『エントリ』の例では、『属性』として、 『属性型』=「objectClass」、『属性値』=「姓情報」を埋め込む。

姓情報エントリのobjectClass)

このように、『objectClass』という『エントリ』が保持できる『属性型』の一覧を保持する『属性』を追加することで、各『エントリ』が保持する『属性』を定義できる。標準的に使用される『属性型』と、それに対応する『objectClass』は既に用意されており、これについては、本ページ:「LDAPで利用される属性型」の「標準の属性型」で説明する。

MUST属性とMAY属性

『objectClass』は、その『エントリ』に格納する『属性型』を規定するものである。例えば、「個人情報」という『objectClass』の場合、個人の「名前」・「生年月日」などの『属性』を格納する。

objectClass: 個人情報 ─ ┬ ─ 『必須(MUST)属性』 ─ → 「名前」・「生年月日」
              └ ─ 『補足(MAY)属性』  ─ → 「電話番号」・「備考欄」

エントリの追加

存在しなかった『属性』が後から必要になる場合がある。そういう状況に柔軟に対応できるように、LDAPでは、1つの『エントリ』が複数の『objectClass』を保持できるようにしている。このため、「個人情報」という『objectClass』を保持する『エントリ』に、別の『objectClass』を追加できる。例えば、「電子メールアドレス情報」という『objectClass』を『エントリ』に追加できる。

複数のobjectClass)

2つのobjectclass

『objectClass』には2つの種類がある。ひとつはエントリの大枠を決めるもの、もうひとつはそのエントリに存在する捕捉情報を決めるものである。

それぞれ、

と呼ぶ。

なお、『structual objectClass』は、エントリの中に必ず存在しなければいけない。また、ふたつ以上あってもいけない。逆に『auxiliary objectClass』は、エントリ中に何個指定しても良い。

structual objectClass と auxiliary objectClass)

上記の例では、

である。

LDAPで利用される属性型

標準の属性型

LDAP では、各『エントリ』の『名前付け属性』として、「c」、「o」、「ou」など、標準的な『名前付け属性』を使用する。これらは「c」で国を、「o」で組織/会社を、「ou」で組織単位を、「cn」で固有の名称(氏名など)を示す。この標準的な『名前付け属性』を使用することで、世の中のすべての存在が1つのツリー内で定義することができる。これは、「組織ツリー」と呼ばれている(これには、世界に存在するディレクトリのルートのエントリが1つである必要がある)。

代表的な『名前付け属性』と、対応する『objectClass』を以下に示す。

項番名前付け属性
その他の属性
オブジェクトクラス説明
objectClasstop(共通)そのクラス自身および全ての親クラス
c (countryName)country(国)国の名前
description国の説明
o (organizationName)organization(組織)組織の名前
l (localityName)都市、地域
ou (organizationUnitName?)organizationUnit(組織単位)部署などの名前
l (localityName)都市、地域

※ 黄色網掛けは、『名前付け属性』
※ LDAPで使用される『属性型』の文法はRFC2552で、種類はRFC2556で定義されている。

組織ツリー

組織ツリー)

製品毎の属性型

LDAPとActive Directoryの『名前付け属性』の対応

項番名前付け属性
LDAPActive Directory
1c(国)(サポートされていない)
2o(組織)dc(ドメイン構成要素)
3ou(組織単位)ou(組織単位)
4cn(一般名)cn(一般名)
項番名前付け属性objectClass
dc(ドメイン構成要素)domainDns
ou(組織単位)organizationalUnit
cn(一般名)user

ドメイン構成要素ツリー

ドメイン構成要素ツリー

LDIF(LDAPデータ交換フォーマット)

『LDIF (LDAPデータ交換フォーマット)』は、
LDAPの『エントリ』を簡単なテキスト形式で表現するために利用される。
LDAPツール(LDAPのAPIライブラリ)は、入出力に『LDIF』を使用する。
『LDIF』による『エントリ』の基本的なテキスト形式については下記URLのページが参考になる。

LDAPで、ディレクトリを検索する

LDAPは、クライアントからの要求にサーバが応答する、クライアント・サーバ型のプロトコルである。

LDAPシステムは、以下の流れでディレクトリ内を検索する。

<LDAPの検索オペレーション>
・LDAPクライアントが、検索条件を指定し、検索要求を送信する。
・要求を受けたLDAPサーバは、その内容に対応する『エントリ』を探索する。
・『エントリ』が見つかったら、さらに指定された『属性』を探索する。
・問い合わせのあった『属性』をクライアントに返却する。

以上が、LDAPで『エントリ』を検索する実際の流れとなる。

上記の一連の流れを『オペレーション』という。『オペレーション』には、その内容に応じて複数のパターンが用意されている。例えば、前述の『オペレーション』は『検索オペレーション』という。LDAPには、『検索オペレーション』以外に、代表的なものとして『エントリ』の『追加、変更、削除を行う各オペレーション』、LDAPサーバを不正に利用させないようにするための『認証オペレーション』がある。LDAPの場合、認証をするための手続きをバインドという。

検索オペレーションの基本

LDAPには複数の『オペレーション』が存在するが、ディレクトリ サービスにアクセスするためのプロトコルであることを考慮し、検索用に最適化されている。

『検索オペレーション』では、LDAPクライアントが、検索要求を送信する。
検索要求とは、SQLのSELECT文のような、LDAPサーバの理解できる言葉である。

例えば、以下は、電話番号が03から始まる病院の住所を検索する。
検索要求は、主に2つの引き数『フィルタ式』と『取得する属性』を指定する。

filter: (&(telNumber=03*)(businessCategory=病院))
attribute: cn address
⇒ 『フィルタ式』
⇒ 『取得する属性』

『フィルタ式』とはディレクトリの中から対象とする『エントリ』を識別するための条件のことである。

上記の例でいえば、「03から始まる病院」が『フィルタ式』になる。
取得する『属性』は、条件に一致した『エントリ』のどの『属性値』を取り出すかを指定する。
※ LDAPで使用される『フィルタ式』の書式は、RFC2254に定義されている。

フィルタ式

『フィルタ式』の記述方法について詳しく説明する。

filter: (&(telNumber=03*)(businessCategory=病院))

この条件は、「03で始まる」電話番号の『エントリ』を検索することを意味する。
「telNumber」という『属性型』の『属性値』が「03で始まる」『エントリ』ということになる。
「03*」が「03で始まる」ことを表し、「*」がない場合は「03」そのものを意味する。

同様に、この条件も「businessCategory」という『属性型』の『属性値』が「病院」である『エントリ』を検索することを意味する。ここには「*」がないため、「病院」そのものを意味する。

これは、かっこで括られたその後に続くすべての条件がすべて成り立っていなければならないことを表す。例えば以下の『フィルタ』があった場合、

(&(A)(B))

これはAとBの両方の条件にマッチしていなければいけないことを表す。

フィルタ式の演算子

『フィルタ式』で使える主な演算子を示す。

取得する属性

前述の『フィルタ式』を用いて特定の『エントリ』を探し出すことができる。
次に、見つかった『エントリ』の情報を取り出す方法について説明する。

必要のない情報まで取り出すと、ネットワークやサーバ、クライアントに余計な負荷をかけてしまう。
そのため、『検索オペレーション』には、『エントリ』を探すための『フィルタ式』に加え、
見つかった『エントリ』のどの『属性』を取得するかを指定できる。

先程のディレクトリから電話番号が「03」で始まる「病院」で見つかった『エントリ』の、
「名前」と「住所」の『属性』を取り出す検索要求は以下のとおりになる。

filter: (&(telNumber=03*)(businessCategory=病院))
attribute: cn address

LDAPのログ出力

WindowsのActive Directoryには、以下の様なログがあるもよう。

イベント・ログ

サーバーのトレース

クライアントのトレース

用語集

ディレクトリ サービス(LDAPサーバ)関連

データ構造

ディレクトリ エントリの検索処理

Active Directory


Tags: :Active Directory, :認証基盤, :ディレクトリ サービス


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS