Zkušenosti s Zend_Auth_Adapter_Ldap

V nové verzi Zend Framework 1.5 byla do Zend_Auth přidána podpora pro LDAP. Protože u mě v práci se bez toho neobejde ani ta nejjednoduší aplikace, zkusil jsem ho a seznámím vás s problémy na které jsem narazil a jak jsem je obešel.

Nejprve standarní řešení přes Ldap modul v PHP. Něco o našem LDAPu, používáme port 1636 a pro bind vlastní DN, které kopíruje naší strukturu. Pro bind nepotřebuje aplikace žádného vlastního uživatele použije se jméno a heslo toho kdo se hlásí. Část kódu, která je podstatná pro naše porovnání.

/**
     * Autentizace proti OpenLDAP Usermap (SSU)
     * @param string $uid
     * @param string $pass
     * @return bool
     */
    private function Autentizace_LDAP($uid,$pass)
    {
        $ds = ldap_connect($this->_config->ldaphost);
        @$r = ldap_bind($ds, "cvutLoginName=$uid,ou=People,ou=usermap,o=cvut,c=cz",$pass);
        ldap_close($ds);
        if ($r)
        {
            $this->logger->info("Uspesna autentizace k LDAP ($uid)");
            return true;
        }
        else
        {
            $this->logger->error("Chyba autentizace k LDAP ($uid)");
            return false;
        }
    }

V Zendu se to řeší pomocí tohoto kódu, který je odvozen od toho v manuálu, ale musel projít úpravou v sekci $options, protože LDAP modul v Auth nějak nepočítá s tím, že nemáte uživatele pro přístup k Ldapu, což je pokud vím dost běžná situace.

class AuthController extends Zend_Controller_Action
{
    function indexAction()
    {
      $username = $this->_request->getParam('username');
      $password = $this->_request->getParam('password');
$auth = Zend_Auth::getInstance();
   $registry = Zend_Registry::getInstance();
      $config=$registry->get('config');
      $log_path = $config->ldap->log_path;
      $options = $config->ldap->toArray();
     // modifikovani options
      $options['server1']['username'] = "cvutloginname=$username,ou=People,ou=usermap,o=cvut,c=cz";
      $options['server1']['password'] = $password;
      unset($options['log_path']);
      $adapter = new Zend_Auth_Adapter_Ldap($options, $username, $password);
      $result = $auth->authenticate($adapter);
      if ($log_path)
      {
          $messages = $result->getMessages();
          $logger = new Zend_Log();
          $logger->addWriter(new Zend_Log_Writer_Stream($log_path));
          //$filter = new Zend_Log_Filter_Priority(Zend_Log::DEBUG);
          $filter = new Zend_Log_Filter_Priority(Zend_Log::INFO);
          $logger->addFilter($filter);
          foreach ($messages as $i => $message)
          {
              if ($i-- > 1) { // $messages[2] and up are log messages
                  $message = str_replace("\n", "\n  ", $message);
                  $logger->log("Ldap: $i: $message", Zend_Log::DEBUG);
              }
          }
      }
      // vypis
      if ($result->isValid())
      {
      $this->view->status = "You are logged-in as " . $auth->getIdentity() . "<br>\n";
      }
      else
      {
      $this->view->status = "Error. You are not logged. <a href='../../'>Please login again</a>.";
      }
    }
}

ještě moje options:

[stage]
ldap.log_path = ../logs/ldap.log;
Typical options for OpenLDAP
ldap.server1.host = usermap.cvut.cz
ldap.server1.port = 1636
ldap.server1.useSsl = true
ldap.server1.baseDn = "ou=People,ou=usermap,o=cvut,c=cz"
ldap.server1.bindRequiresDn = true
ldap.server1.accountFilterFormat = "(&(objectClass=person)(uid=%s))"

v další fázi se obvykle ještě snažíme vytáhnout některá data jako je osobní číslo podle kterého se potom pracuje s aplikací, ale to bude dobře možné až pomocí Zend_Ldap_Ext, která je zatím ve vývoji, ale můžete samozřejmě použít stávající Ldap funkce v php.