Zend Framework の紹介

 Learning Zend Framework

appendix

 Zend Framework リファレンス


  • 第36章 Zend_Gdata
  • 第37章 Zend_Http
  • 第38章 Zend_InfoCard
  • 第39章 Zend_Json
  • 第40章 Zend_Layout
  • 第41章 Zend_Ldap
  • 第42章 Zend_Loader
  • 第43章 Zend_Locale
  • 第44章 Zend_Log
  • 第45章 Zend_Mail
  • 第46章 Zend_Markup
  • 第47章 Zend_Measure
  • 第48章 Zend_Memory
  • 第49章 Zend_Mime
  • 第50章 Zend_Navigation
  • 第51章 Zend_Oauth
  • 第52章 Zend_OpenId
  • 第53章 Zend_Paginator
  • 第54章 Zend_Pdf
  • 第55章 Zend_ProgressBar
  • 第56章 Zend_Queue
  • 第57章 Zend_Reflection
  • 第58章 Zend_Registry
  • 第59章 Zend_Rest

  • 第60章 Zend_Search_Lucene
  • 第61章 Zend_Serializer
  • 第62章 Zend_Server
  • 第63章 Zend_Service
  • 第64章 Zend_Session
  • 第65章 Zend_Soap
  • 第66章 Zend_Tag
  • 第67章 Zend_Test
  • 第68章 Zend_Text
  • 第69章 Zend_TimeSync
  • 第70章 Zend_Tool
  • 第71章 Zend_Tool_Framework
  • 第72章 Zend_Tool_Project
  • 第73章 Zend_Translate
  • 第74章 Zend_Uri
  • 第75章 Zend_Validate
  • 第76章 Zend_Version
  • 第77章 Zend_View
  • 第78章 Zend_Wildfire
  • 第79章 Zend_XmlRpc
  • ZendX_Console_Process_Unix
  • ZendX_JQuery
  • Translation 70.6% Update 2010-11-28 - Revision 23415

    第41章 Zend_Ldap

    目次

    41.1. 導入
    41.1.1. 動作原理
    41.1.1.1. バインド時のユーザ名自動正規化
    41.1.1.2. アカウント名の正規化
    41.1.1.3. 複数ドメインの認証とフェイルオーバー
    41.2. API概要
    41.2.1. 設定/オプション
    41.2.2. APIリファレンス
    41.2.2.1. Zend_Ldap
    41.2.2.1.1. Zend_Ldap_Collection
    41.2.2.2. Zend_Ldap_Attribute
    41.2.2.3. Zend_Ldap_Dn
    41.2.2.4. Zend_Ldap_Filter
    41.2.2.5. Zend_Ldap_Node
    41.2.2.6. Zend_Ldap_Node_RootDse
    41.2.2.6.1. OpenLDAP
    41.2.2.6.2. ActiveDirectory
    41.2.2.6.3. eDirectory
    41.2.2.7. Zend_Ldap_Node_Schema
    41.2.2.7.1. OpenLDAP
    41.2.2.7.2. ActiveDirectory
    41.2.2.8. Zend_Ldif_Encoder
    41.3. 利用シナリオ
    41.3.1. 認証シナリオ
    41.3.1.1. OpenLDAP
    41.3.1.2. ActiveDirectory
    41.3.2. 基本的なCRUD操作
    41.3.2.1. LDAPからデータを取得
    41.3.2.2. LDAPにデータを追加
    41.3.2.3. LDAPからデータを削除
    41.3.2.4. LDAPを更新
    41.3.3. 拡張された操作
    41.3.3.1. LDAPで項目をコピーまたは移動
    41.4. ツール
    41.4.1. DN 文字列の作成及び変更
    41.4.2. 検索フィルタを作成するためにフィルタAPIを使う
    41.4.3. 属性APIを使用するLDAP項目の変更
    41.5. Zend_Ldap_Nodeを使用してLDAPツリーへのオブジェクト指向アクセス
    41.5.1. CRUD基本操作
    41.5.1.1. LDAPからデータを取得
    41.5.1.1.1. DNでノードを取得
    41.5.1.1.2. ノードのサブツリーを検索
    41.5.1.2. LDAPに新規ノードを追加
    41.5.1.3. LDAPからノードを削除
    41.5.1.4. LDAP上のノードを更新
    41.5.2. 派生的な操作
    41.5.2.1. LDAPでノードをコピーまたは移動
    41.5.3. ツリーの走査
    41.6. LDAPサーバから情報を取得
    41.6.1. ルートDSE
    41.6.2. 参照するスキーマ
    41.6.2.1. OpenLDAP
    41.6.2.2. ActiveDirectory
    41.7. LDIFへ、または、からのLDAPデータシリアライズ
    41.7.1. LDIFへのLDAP項目シリアライズ
    41.7.2. LDIF文字列をLDAP項目に非シリアライズ化

    41.1. 導入

    Zend_LdapLDAP操作を行うクラスです。 バインドだけが可能で、 LDAP ディレクトリ内のエントリの検索や変更には対応していません。

    41.1.1. 動作原理

    現在このコンポーネントは、OpenLDAPまたはActiveDirectory(AD)サーバのような 単一のLDAPサーバへのバインディングを概念的に表現して、 LDAPサーバに対する活動を実行できる 主要なZend_Ldapクラスから成ります。 バインディングのパラメータは、明示的に、または、オプション配列の形で提供されるかもしれません。 Zend_Ldap_Nodeは、 単一のLDAPノードのためにオブジェクト指向インタフェースを提供します。 そして、LDAPベースのドメイン・モデルのために、 アクティブ・レコードのようなインターフェースの基盤を作ることに使うことができます。

    属性の設定や取得 (日付値、パスワード、ブール値など)のような LDAP項目上での活動の実行や (Zend_Ldap_Attribute)、 LDAPフィルタ文字列の作成や修正 (Zend_Ldap_Filter)、 LDAP識別名 (DN)の操作 (Zend_Ldap_Dn) をおこなうためのいくつかのヘルパー・クラスをコンポーネントで提供します。

    その上、 OpenLDAPとActiveDirectoyサーバのZend_Ldap_Node_Schemaのために ブラウズするLDAPスキーマ、 そして OpenLDAPサーバやActiveDirectoryサーバ、 Novell eDirectoryサーバのためのサーバ情報取得 (Zend_Ldap_Node_RootDse)をコンポーネントで抽象します。

    Zend_Ldap クラスの使用法は LDAP サーバの形式によって異なり、 以下のいずれかのパターンとなります。

    OpenLDAP を使用している場合は、以下の例のようになります (AD を使って いない 場合は bindRequiresDn オプションが重要となることに注意しましょう):

    $options = array(
        
    'host'              => 's0.foo.net',
        
    'username'          => 'CN=user1,DC=foo,DC=net',
        
    'password'          => 'pass1',
        
    'bindRequiresDn'    => true,
        
    'accountDomainName' => 'foo.net',
        
    'baseDn'            => 'OU=Sales,DC=foo,DC=net',
    );
    $ldap = new Zend_Ldap($options);
    $acctname $ldap->getCanonicalAccountName('abaker',
                                               
    Zend_Ldap::ACCTNAME_FORM_DN);
    echo 
    "$acctname\n";

    Microsoft AD を使う場合の簡単な例です:

    $options = array(
        
    'host'                   => 'dc1.w.net',
        
    'useStartTls'            => true,
        
    'username'               => 'user1@w.net',
        
    'password'               => 'pass1',
        
    'accountDomainName'      => 'w.net',
        
    'accountDomainNameShort' => 'W',
        
    'baseDn'                 => 'CN=Users,DC=w,DC=net',
    );
    $ldap = new Zend_Ldap($options);
    $acctname $ldap->getCanonicalAccountName('bcarter',
                                               
    Zend_Ldap::ACCTNAME_FORM_DN);
    echo 
    "$acctname\n";

    ここでは、getCanonicalAccountName() メソッドで、 アカウントの DN を取得していることに注意しましょう。 これはただ単に、このクラスに現在存在するコードの例をできるだけ多く見せたいからです。

    41.1.1.1. バインド時のユーザ名自動正規化

    bindRequiresDNTRUEで、 かつ DN 形式のユーザ名がオプションで設定されていない場合、 bind() を DN でないユーザ名でコールするとバインドに失敗します。 しかし、DN 形式のユーザ名がオプションで設定されていれば、 Zend_Ldapはまずそのユーザ名でバインドを行い、 bind()で指定したユーザ名に対応するアカウントの DN を取得した上で 改めてその DN でバインドしなおします。

    この振る舞いはZend_Auth_Adapter_Ldap にとっては重要です。 これは、ユーザが指定したユーザ名を直接 bind() に渡します。

    次の例では、DN でないユーザ名 'abaker' を bind() で使用する方法を示します:

    $options = array(
            
    'host'              => 's0.foo.net',
            
    'username'          => 'CN=user1,DC=foo,DC=net',
            
    'password'          => 'pass1',
            
    'bindRequiresDn'    => true,
            
    'accountDomainName' => 'foo.net',
            
    'baseDn'            => 'OU=Sales,DC=foo,DC=net',
    );
    $ldap = new Zend_Ldap($options);
    $ldap->bind('abaker''moonbike55');
    $acctname $ldap->getCanonicalAccountName('abaker',
                                               
    Zend_Ldap::ACCTNAME_FORM_DN);
    echo 
    "$acctname\n";

    この例において bind() をコールすると、 ユーザ名 'abaker' が DN 形式でないことと bindRequiresDnTRUE であることから、まず 'CN=user1,DC=foo,DC=net' と 'pass1' を用いてバインドします。それから 'abaker' の DN を取得し、 いったんバインドを解除したうえであらためて 'CN=Alice Baker,OU=Sales,DC=foo,DC=net' でバインドしなおします。

    41.1.1.2. アカウント名の正規化

    accountDomainNameおよび accountDomainNameShortオプションは、 次のふたつの目的で使用します。 (1) 複数ドメインによる認証 (どちらか一方が使えないときの代替機能) を実現する。 (2) ユーザ名を正規化する。 特に、名前の正規化の際には accountCanonicalFormオプションで指定した形式を使用します。 このオプションの値は、次のいずれかとなります:

    表 41.1. accountCanonicalFormのオプション

    名前
    ACCTNAME_FORM_DN 1 CN=Alice Baker,CN=Users,DC=example,DC=com
    ACCTNAME_FORM_USERNAME 2 abaker
    ACCTNAME_FORM_BACKSLASH 3 EXAMPLE\abaker
    ACCTNAME_FORM_PRINCIPAL 4 abaker@example.com

    デフォルトの正規化は、アカウントのドメイン名のオプションが どのように設定されているかによって変わります。 accountDomainNameShort が指定されている場合は、デフォルトの accountCanonicalForm の値は ACCTNAME_FORM_BACKSLASH となります。 それ以外の場合は、もし accountDomainName が設定されていればデフォルトは ACCTNAME_FORM_PRINCIPAL となります。

    アカウント名の正規化をすることで、bind() に何が渡されたのかにかかわらずアカウントの識別に用いる文字列が一貫性のあるものになります。 たとえば、ユーザがアカウント名として abaker@example.com あるいは単に abaker だけを指定したとしても、accountCanonicalForm が 3 に設定されていれば正規化後の名前は EXAMPLE\abaker となります。

    41.1.1.3. 複数ドメインの認証とフェイルオーバー

    Zend_Ldap コンポーネント自身は、 複数サーバでの認証を試みません。 しかし、Zend_Ldap はこのような場合に対応するようにも設計されています。 サーバのオプションを指定した配列の配列を順にたどり、 個々のサーバへのバインドを試みるのです。上で説明したように、 bind() は自動的に名前を正規化します。したがって、ユーザが abaker@foo.net を指定したか、あるいは W\bcartercdavis と指定したかにはかかわらず、 bind() メソッドが成功するかどうかは バインド時に認証情報が正しく指定されたかどうかによって決まります。

    次の例では、複数ドメインでの認証と フェイルオーバー機能を実装するために必要な技術を説明します:

    $acctname 'W\\user2';
    $password 'pass2';

    $multiOptions = array(
        
    'server1' => array(
            
    'host'                   => 's0.foo.net',
            
    'username'               => 'CN=user1,DC=foo,DC=net',
            
    'password'               => 'pass1',
            
    'bindRequiresDn'         => true,
            
    'accountDomainName'      => 'foo.net',
            
    'accountDomainNameShort' => 'FOO',
            
    'accountCanonicalForm'   => 4// ACCT_FORM_PRINCIPAL
            
    'baseDn'                 => 'OU=Sales,DC=foo,DC=net',
        ),
        
    'server2' => array(
            
    'host'                   => 'dc1.w.net',
            
    'useSsl'                 => true,
            
    'username'               => 'user1@w.net',
            
    'password'               => 'pass1',
            
    'accountDomainName'      => 'w.net',
            
    'accountDomainNameShort' => 'W',
            
    'accountCanonicalForm'   => 4// ACCT_FORM_PRINCIPAL
            
    'baseDn'                 => 'CN=Users,DC=w,DC=net',
        ),
    );

    $ldap = new Zend_Ldap();

    foreach (
    $multiOptions as $name => $options) {

        echo 
    "Trying to bind using server options for '$name'\n";

        
    $ldap->setOptions($options);
        try {
            
    $ldap->bind($acctname$password);
            
    $acctname $ldap->getCanonicalAccountName($acctname);
            echo 
    "SUCCESS: authenticated $acctname\n";
            return;
        } catch (
    Zend_Ldap_Exception $zle) {
            echo 
    '  ' $zle->getMessage() . "\n";
            if (
    $zle->getCode() === Zend_Ldap_Exception::LDAP_X_DOMAIN_MISMATCH) {
                continue;
            }
        }
    }

    何らかの理由でバインドに失敗すると、その次のセットのサーバオプションでバインドを試みます。

    getCanonicalAccountName() をコールすると、 正規化したアカウント名を取得できます。 これを使用して、アプリケーションから関連データを取得できるようになります。 accountCanonicalForm = 4 をすべてのサーバのオプションに設定することで、 どのサーバを使用する場合にも一貫した正規化が行えるようになっています。

    ドメイン部つきのアカウント名 (単なる abaker ではなく abaker@foo.netFOO\abaker など) を指定した場合は、そのドメインが設定済みのオプションのどれとも一致しなければ 特別な例外 LDAP_X_DOMAIN_MISMATCH が発生します。 この例外は、そのアカウントがサーバに見つからないことを表します。 この場合はバインドは行われず、 サーバとの余計な通信は発生しません。 この例では continue という指示は無意味であることに注意しましょう。 しかし、実際には、エラー処理やデバッグなどのために LDAP_NO_SUCH_OBJECTLDAP_INVALID_CREDENTIALS だけではなく LDAP_X_DOMAIN_MISMATCH もチェックすることになるでしょう。

    上のコードは、Zend_Auth_Adapter_Ldap の中で使用するコードと非常によく似ています。実際のところ、 複数ドメインとフェイルオーバー機能をもつ LDAP 基本認証を行うのなら、 この認証アダプタを使用する (あるいはコードをコピーする) ことをおすすめします。

    digg delicious meneame google twitter technorati facebook

    Comments

    Loading...