symfonyでユーザ認証にLDAPを利用する

前提条件

普段のユーザ認証には、sfDoctrineGuardPluginを利用している
LDAPまわりは、Zend FrameworkのZend_Ldap利用する

Zend Frameworkを用意する

http://framework.zend.com/
今回は、最新版(1.9.5)を使いました。

symfonyZend Frameworkの場所を明示 & 認証に使う関数変更

# apps/frontend/config/app.yml

all:
  zend_lib_dir: /home/takitake/ZendFramework-1.9.5-minimal/library
  sf_guard_plugin:
    check_password_callable: [LDAP, checkPassword]

参照しやすいように、上記の様にZend Frameworkの位置を明示しときます。
また、認証には LDAPクラスのcheckPassword関数使いますよ、と宣言。

autoloadに登録

<?php
// apps/frontend/config/frontendConfiguration.class.php

class frontendConfiguration extends sfApplicationConfiguration
{
  public function initialize()
  {
    parent::initialize();// load symfony autoloading first

    // Integrate Zend Framework
    if ($sf_zend_lib_dir = sfConfig::get('app_zend_lib_dir'))
    {
      set_include_path($sf_zend_lib_dir.PATH_SEPARATOR.get_include_path());
      require_once($sf_zend_lib_dir.'/Zend/Loader/Autoloader.php');
      $autoloader = Zend_Loader_Autoloader::getInstance();
      $autoloader->setFallbackAutoloader(true);
      spl_autoload_register(array('Zend_Loader_Autoloader', 'autoload'));
    }
  }

  public function configure()
  {
  }
}

ここ、参考ページと異なります。
新しいZend Frameworkだと、Zend_LoaderではなくZend_Loader_Autoloader使うらしいです。

LDAPクラス作成

<?php
// apps/frontend/lib/LDAP.class.php

class LDAP
{
  public static function checkPassword($username, $password)
  {
    // LDAPサーバへ問い合わせる
    $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);

    try
    {
      $ldap->bind($username, $password);
      $ldap->getCanonicalAccountName($username);

      // 認証成功した場合は、trueを返す
      return true;
    }
    catch (Zend_Ldap_Exception $zle)
    {
      // 認証失敗した場合は、falseを返す
      return false;
    }
  }
}