1 <?xml version="1.0" encoding="UTF-8"?>
3 <!-- EN-Revision: 20792 -->
4 <sect1 id="zend.ldap.introduction">
8 <classname>Zend_Ldap</classname> は <acronym>LDAP</acronym>操作を行うクラスです。
10 <acronym>LDAP</acronym> ディレクトリ内のエントリの検索や変更には対応していません。
13 <sect2 id="zend.ldap.introduction.theory-of-operations">
17 現在このコンポーネントは、OpenLDAPまたはActiveDirectory(AD)サーバのような
18 単一の<acronym>LDAP</acronym>サーバへのバインディングを概念的に表現して、
19 <acronym>LDAP</acronym>サーバに対する活動を実行できる
20 主要な<classname>Zend_Ldap</classname>クラスから成ります。
21 バインディングのパラメータは、明示的に、または、オプション配列の形で提供されるかもしれません。
22 <classname>Zend_Ldap_Node</classname>は、
23 単一の<acronym>LDAP</acronym>ノードのためにオブジェクト指向インタフェースを提供します。
24 そして、<acronym>LDAP</acronym>ベースのドメイン・モデルのために、
25 アクティブ・レコードのようなインターフェースの基盤を作ることに使うことができます。
29 属性の設定や取得 (日付値、パスワード、ブール値など)のような
30 <acronym>LDAP</acronym>項目上での活動の実行や
31 (<classname>Zend_Ldap_Attribute</classname>)、
32 <acronym>LDAP</acronym>フィルタ文字列の作成や修正
33 (<classname>Zend_Ldap_Filter</classname>)、
34 <acronym>LDAP</acronym>識別名 (DN)の操作
35 (<classname>Zend_Ldap_Dn</classname>)
36 をおこなうためのいくつかのヘルパー・クラスをコンポーネントで提供します。
41 OpenLDAPとActiveDirectoyサーバの<classname>Zend_Ldap_Node_Schema</classname>のために
42 ブラウズする<acronym>LDAP</acronym>スキーマ、
44 OpenLDAPサーバやActiveDirectoryサーバ、
45 Novell eDirectoryサーバのためのサーバ情報取得
46 (<classname>Zend_Ldap_Node_RootDse</classname>)をコンポーネントで抽象します。
50 <classname>Zend_Ldap</classname> クラスの使用法は <acronym>LDAP</acronym> サーバの形式によって異なり、
55 OpenLDAP を使用している場合は、以下の例のようになります (AD を使って
56 <emphasis>いない</emphasis> 場合は <emphasis>bindRequiresDn</emphasis>
57 オプションが重要となることに注意しましょう):
60 <programlisting language="php"><![CDATA[
62 'host' => 's0.foo.net',
63 'username' => 'CN=user1,DC=foo,DC=net',
64 'password' => 'pass1',
65 'bindRequiresDn' => true,
66 'accountDomainName' => 'foo.net',
67 'baseDn' => 'OU=Sales,DC=foo,DC=net',
69 $ldap = new Zend_Ldap($options);
70 $acctname = $ldap->getCanonicalAccountName('abaker',
71 Zend_Ldap::ACCTNAME_FORM_DN);
76 Microsoft AD を使う場合の簡単な例です:
79 <programlisting language="php"><![CDATA[
81 'host' => 'dc1.w.net',
82 'useStartTls' => true,
83 'username' => 'user1@w.net',
84 'password' => 'pass1',
85 'accountDomainName' => 'w.net',
86 'accountDomainNameShort' => 'W',
87 'baseDn' => 'CN=Users,DC=w,DC=net',
89 $ldap = new Zend_Ldap($options);
90 $acctname = $ldap->getCanonicalAccountName('bcarter',
91 Zend_Ldap::ACCTNAME_FORM_DN);
96 ここでは、<methodname>getCanonicalAccountName()</methodname> メソッドで、
97 アカウントの DN を取得していることに注意しましょう。
98 これはただ単に、このクラスに現在存在するコードの例をできるだけ多く見せたいからです。
101 <sect3 id="zend.ldap.introduction.theory-of-operations.automatic-username-canonicalization">
102 <title>バインド時のユーザ名自動正規化</title>
105 <emphasis>bindRequiresDN</emphasis> が <constant>TRUE</constant>で、
106 かつ DN 形式のユーザ名がオプションで設定されていない場合、
107 <methodname>bind()</methodname> を DN でないユーザ名でコールするとバインドに失敗します。
108 しかし、DN 形式のユーザ名がオプションで設定されていれば、
109 <classname>Zend_Ldap</classname>はまずそのユーザ名でバインドを行い、
110 <methodname>bind()</methodname>で指定したユーザ名に対応するアカウントの DN を取得した上で
111 改めてその DN でバインドしなおします。
116 linkend="zend.auth.adapter.ldap"><classname>Zend_Auth_Adapter_Ldap</classname></link>
118 これは、ユーザが指定したユーザ名を直接 <methodname>bind()</methodname> に渡します。
122 次の例では、DN でないユーザ名 '<emphasis>abaker</emphasis>'
123 を <methodname>bind()</methodname> で使用する方法を示します:
126 <programlisting language="php"><![CDATA[
128 'host' => 's0.foo.net',
129 'username' => 'CN=user1,DC=foo,DC=net',
130 'password' => 'pass1',
131 'bindRequiresDn' => true,
132 'accountDomainName' => 'foo.net',
133 'baseDn' => 'OU=Sales,DC=foo,DC=net',
135 $ldap = new Zend_Ldap($options);
136 $ldap->bind('abaker', 'moonbike55');
137 $acctname = $ldap->getCanonicalAccountName('abaker',
138 Zend_Ldap::ACCTNAME_FORM_DN);
143 この例において <methodname>bind()</methodname> をコールすると、
144 ユーザ名 '<emphasis>abaker</emphasis>' が DN 形式でないことと
145 <emphasis>bindRequiresDn</emphasis> が <constant>TRUE</constant> であることから、まず
146 '<command>CN=user1,DC=foo,DC=net</command>' と '<emphasis>pass1</emphasis>'
147 を用いてバインドします。それから '<emphasis>abaker</emphasis>' の DN を取得し、
148 いったんバインドを解除したうえであらためて
149 '<command>CN=Alice Baker,OU=Sales,DC=foo,DC=net</command>'
154 <sect3 id="zend.ldap.introduction.theory-of-operations.account-name-canonicalization">
155 <title>アカウント名の正規化</title>
158 <emphasis>accountDomainName</emphasis>および
159 <emphasis>accountDomainNameShort</emphasis>オプションは、
161 (1) 複数ドメインによる認証 (どちらか一方が使えないときの代替機能) を実現する。
164 <emphasis>accountCanonicalForm</emphasis>オプションで指定した形式を使用します。
165 このオプションの値は、次のいずれかとなります:
168 <table id="zend.ldap.using.theory-of-operation.account-name-canonicalization.table">
169 <title>accountCanonicalFormのオプション</title>
181 <constant>ACCTNAME_FORM_DN</constant>
184 <entry>CN=Alice Baker,CN=Users,DC=example,DC=com</entry>
188 <constant>ACCTNAME_FORM_USERNAME</constant>
191 <entry>abaker</entry>
195 <constant>ACCTNAME_FORM_BACKSLASH</constant>
198 <entry>EXAMPLE\abaker</entry>
202 <constant>ACCTNAME_FORM_PRINCIPAL</constant>
205 <entry><filename>abaker@example.com</filename></entry>
212 デフォルトの正規化は、アカウントのドメイン名のオプションが
213 どのように設定されているかによって変わります。
214 <emphasis>accountDomainNameShort</emphasis> が指定されている場合は、デフォルトの
215 <emphasis>accountCanonicalForm</emphasis> の値は
216 <constant>ACCTNAME_FORM_BACKSLASH</constant> となります。
217 それ以外の場合は、もし <emphasis>accountDomainName</emphasis>
219 <constant>ACCTNAME_FORM_PRINCIPAL</constant> となります。
223 アカウント名の正規化をすることで、<methodname>bind()</methodname>
224 に何が渡されたのかにかかわらずアカウントの識別に用いる文字列が一貫性のあるものになります。
226 <filename>abaker@example.com</filename> あるいは単に <emphasis>abaker</emphasis>
227 だけを指定したとしても、<emphasis>accountCanonicalForm</emphasis>
228 が 3 に設定されていれば正規化後の名前は
229 <emphasis>EXAMPLE\abaker</emphasis> となります。
233 <sect3 id="zend.ldap.introduction.theory-of-operations.multi-domain-failover">
234 <title>複数ドメインの認証とフェイルオーバー</title>
237 <classname>Zend_Ldap</classname> コンポーネント自身は、
239 しかし、<classname>Zend_Ldap</classname> はこのような場合に対応するようにも設計されています。
240 サーバのオプションを指定した配列の配列を順にたどり、
241 個々のサーバへのバインドを試みるのです。上で説明したように、
242 <methodname>bind()</methodname> は自動的に名前を正規化します。したがって、ユーザが
243 <filename>abaker@foo.net</filename> を指定したか、あるいは <emphasis>W\bcarter</emphasis>
244 や <emphasis>cdavis</emphasis> と指定したかにはかかわらず、
245 <methodname>bind()</methodname> メソッドが成功するかどうかは
246 バインド時に認証情報が正しく指定されたかどうかによって決まります。
251 フェイルオーバー機能を実装するために必要な技術を説明します:
254 <programlisting language="php"><![CDATA[
255 $acctname = 'W\\user2';
258 $multiOptions = array(
260 'host' => 's0.foo.net',
261 'username' => 'CN=user1,DC=foo,DC=net',
262 'password' => 'pass1',
263 'bindRequiresDn' => true,
264 'accountDomainName' => 'foo.net',
265 'accountDomainNameShort' => 'FOO',
266 'accountCanonicalForm' => 4, // ACCT_FORM_PRINCIPAL
267 'baseDn' => 'OU=Sales,DC=foo,DC=net',
270 'host' => 'dc1.w.net',
272 'username' => 'user1@w.net',
273 'password' => 'pass1',
274 'accountDomainName' => 'w.net',
275 'accountDomainNameShort' => 'W',
276 'accountCanonicalForm' => 4, // ACCT_FORM_PRINCIPAL
277 'baseDn' => 'CN=Users,DC=w,DC=net',
281 $ldap = new Zend_Ldap();
283 foreach ($multiOptions as $name => $options) {
285 echo "Trying to bind using server options for '$name'\n";
287 $ldap->setOptions($options);
289 $ldap->bind($acctname, $password);
290 $acctname = $ldap->getCanonicalAccountName($acctname);
291 echo "SUCCESS: authenticated $acctname\n";
293 } catch (Zend_Ldap_Exception $zle) {
294 echo ' ' . $zle->getMessage() . "\n";
295 if ($zle->getCode() === Zend_Ldap_Exception::LDAP_X_DOMAIN_MISMATCH) {
303 何らかの理由でバインドに失敗すると、その次のセットのサーバオプションでバインドを試みます。
307 <methodname>getCanonicalAccountName()</methodname> をコールすると、
309 これを使用して、アプリケーションから関連データを取得できるようになります。
310 <emphasis>accountCanonicalForm = 4</emphasis> をすべてのサーバのオプションに設定することで、
311 どのサーバを使用する場合にも一貫した正規化が行えるようになっています。
315 ドメイン部つきのアカウント名 (単なる <emphasis>abaker</emphasis>
316 ではなく <filename>abaker@foo.net</filename> や <emphasis>FOO\abaker</emphasis> など)
317 を指定した場合は、そのドメインが設定済みのオプションのどれとも一致しなければ
318 特別な例外 <constant>LDAP_X_DOMAIN_MISMATCH</constant> が発生します。
319 この例外は、そのアカウントがサーバに見つからないことを表します。
322 この例では <emphasis>continue</emphasis> という指示は無意味であることに注意しましょう。
323 しかし、実際には、エラー処理やデバッグなどのために
324 <constant>LDAP_NO_SUCH_OBJECT</constant> と <constant>LDAP_INVALID_CREDENTIALS</constant>
325 だけではなく <constant>LDAP_X_DOMAIN_MISMATCH</constant> もチェックすることになるでしょう。
330 linkend="zend.auth.adapter.ldap"><classname>Zend_Auth_Adapter_Ldap</classname></link>
331 の中で使用するコードと非常によく似ています。実際のところ、
332 複数ドメインとフェイルオーバー機能をもつ <acronym>LDAP</acronym> 基本認証を行うのなら、
333 この認証アダプタを使用する (あるいはコードをコピーする) ことをおすすめします。