www.SAMURAJ-cz.com 

24.04.2024 Jiří Translate to English by Google     VÍTEJTE V MÉM SVĚTĚ

Články

Jak na LDAP a LDAPS v PHP pod Windows

Pátek, 02.11.2007 16:52 | Samuraj - Petr Bouška |
Tento článek slouží jako upozornění na možnosti, které nám dává PHP. V PHP můžeme přistupovat do adresářových služeb, například Active Directory, což se hodí pro řadu aplikací (třeba na intranetu). Také uvádí postup, jak rozchodit využití LDAPS pod Windows.

Teoretický popis LDAPu je v článku Adresářové služby a LDAP. Pokud se na problematiku podíváme velmi přibližně, tak adresář je databáze a LDAP jsou funkce pro přístup k databázi. Proto v teoretickém použití LDAPu z PHP není problém. Pro PHP existuje rozšíření (extension) php_ldap, které implementuje operace LDAPu.

LDAP

Pro zprovoznění LDAPu v PHP na operačním systému Windows, potřebujeme pouze zapnout PHP extension php_ldap. To provedeme přidáním řádku do sekce extension v souboru php.ini (případně jeho odkomentováním).

extension=php_ldap.dll

Potom již můžeme jednoduše přistupovat k LDAPu. Popis funkcí je v manuálu LDAP Functions, je zde implementováno všech 9 standardních operací z LDAP v3. Některé jsou rozděleny do více funkcí a je zde řada doplňujících funkcí pro jednodušší použití. Velice stručně se zmíním o základních funkcích.

ldap_connect()
Vytvoří spojení na zadaný LDAP server, vrací ID linku nebo false. Pokud nespecifikujeme, tak se pro LDAP použije standardní port 389.
ldap_set_option()
Nastaví hodnotu specifikované vlastnosti, třeba verze LDAPu.
ldap_bind()
Navázání k adresáři pomocí ID linky. Provádí se autentizace podle jména a hesla, pokud se nezadá, tak se pokusí o anonymní připojení. Většinou se tak chová i v případě, pokud se vyplní pouze jméno a ne heslo. Server pak často vrátí true, to se stane i v případě AD, i když anonymní připojení není povoleno (a další přístup k adresáři není funkční). Jméno by se mělo zadávat pomocí DN (CN=Uzivatel,OU=Users,DC=firma,DC=local) , ale pro AD funguje i zadání pouze username (uzivatel) nebo UPN (uzivatel@firma.local).
ldap_search()
Operace search z LDAPu. Zadáváme výchozí bod hledání a filtr, další parametry jsou volitelné. Vrací ID výsledku nebo false.
ldap_get_entries()
Jedna z možností jak získat záznamy vrácené funkcí search (a dalších). Vrací vícerozměrné pole, kde jsou jednotlivé záznamy a pro každý záznam jeho atributy.
ldap_add()
Vložení nového záznamu s daným DN a určenými atributy.
ldap_compare()
Porovnání atributu s hodnotou pro daný záznam.
ldap_close()
Korektní ukončení session, jedná se pouze o alias k ldap_unbind().

Ještě uvádím jednoduchý příklad, který se připojí k AD pod uživatelem a provede jednoduché hledání a výpis pár hodnot. Pro správné použití chybí ošetření řady událostí apod.

<?php
function ldapQuery($filter, $baseDN = "OU=firma,DC=firma,DC=local", $server = "192.168.0.1") {
  $ldapCon = ldap_connect($server);
  if($ldapCon) {
    ldap_set_option($ldapCon, LDAP_OPT_PROTOCOL_VERSION, 3);    // AD podporuje LDAPv3
    ldap_set_option($ldapCon, LDAP_OPT_REFERRALS, 0);           // pro AD se doporučuje vypnout referrals
    $res = ldap_bind($ldapCon, "CN=Uzivatel,OU=Users,DC=firma,DC=local", "Password");
    if($res === false) { echo "<p>Autentizace selhala.</p>";  ldap_close($ldapCon); return false; }
    $rec = ldap_search($ldapCon, $baseDN, $filter); 
    echo "<p>Počet vyhledaných záznamů: " . ldap_count_entries($ldapCon, $rec) . "</p>";
    $info = ldap_get_entries($ldapCon, $rec);      
    for($i=0; $i<$info["count"]; $i++) {
      echo "DN: ".iconv("UTF-8", "ISO-8859-2", $info[$i]["dn"])."<br />";
      echo "První CN: ".iconv("UTF-8", "ISO-8859-2", $info[$i]["cn"][0])."<br />";
      echo "První email: ".$info[$i]["mail"][0]."<br /><hr />";
    }
    ldap_close($ldapCon);
  } else { echo "<p>Nepodařilo se připojit k LDAP serveru.</p>"; ldap_close($ldapCon); return false; }
}
ldapQuery("(memberOf=CN=Skupina,OU=firma,DC=firma,DC=local)");
?>

Pozn.: Adresářové služby používají kódování UTF-8, takže pokud na stránce máme nějaké jiné, musíme hodnoty převádět.

Pozn.: Pokud v AD používáme v názvech (v DN) diakritiku, tak v příkazech můžeme použít znaky bez diakritiky (a nemusíme pak řešit problém s kódováním).

LDAPS

Při běžném použití LDAPu probíhá komunikace mezi webovým serverem a adresářovým serverem (budu uvažovat AD) v otevřené formě a při zachycení komunikace je vše čitelné. Největší nebezpečí je u autentizace operací bind.

Pokud je pro nás problém pouze autentizace, tak můžeme použít SASL metodu autentizace. Pokud nám jde o zabezpečení veškerých dat, tak potřebujeme šifrovat veškerou komunikaci a to můžeme buď pomocí SSL nebo TLS. Já se budu věnovat SSL. LDAP, který běží nad SSL, se označuje jako LDAPS.

Pozn.: Pokud jsou ještě nějaká důležitá data (například právě autentizace uživatele do AD) posílána z klienta na webový server, tak je dobré šifrovat pomocí SSL i tuto komunikaci (HTTPS).

Jak rozchodit LDAPS

  1. LDAPS používá stejnou knihovnu jako LDAP, takže nejprve musíme zapnout extension php_ldap.dll
  2. Protože chceme používat SSL, tak musíme rozchodit Apache se SSL, to je popsáno v článku Apache server (EasyPHP) se SSL na Windows.
  3. Musíme mít zprovozněné LDAPS na adresářovém serveru, takže AD server musí mít certifikát.
  4. Knihovna php_ldap.dll má v sobě napevno specifikovánu cestu ke svému konfiguračnímu souboru, která je C:\openldap\sysconf\ldap.conf (v Linuxu /etc/openldap/ldap.conf). Musíme tedy vytvořit tyto adresáře a do nich soubor, do kterého vložíme následující řádek
TLS_REQCERT never    // nekontroluje se certifikát serveru

A to je vše, nyní již můžeme využívat šifrované LDAPS. Abychom použili LDAPS v PHP, tak stačí ve funkci ldap_connect použít adresu serveru ldaps://192.168.0.1, případně s určením standardního portu 636 ldap_connect("192.168.0.1", 636).

Výše uvedený postup je zjednodušený, nepoužíváme certifikát klienta a ani nekontrolujeme certifikát serveru. Většina návodů na internetu obsahuje kroky, kde se stáhne certifikát kořenové autority, od které má adresářový server svůj certifikát. Ten se pomocí OpenSSL převede do formátu PEM a přidá se do konfiguračního souboru ldap.conf pomocí parametru TLS_CACERT.

Pozn.: Narazil jsem na problém, když startoval Apache a php_ldap.dll se snažilo načíst certifikát, tak celý server spadnul. Pomohlo přehrání knihovny php_ldap.dll z poslední verze PHP (php-4.4.7-Win32.zip).

Ladění

Pro řešení problémů s LDAPem můžeme zapnout debugovací mód. To provedeme zadáním následujícího příkazu do kódu ještě před ldap_connect.

ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);

Následně se do logu errors.log Apache serveru zapisují podrobně všechny prováděné operace s LDAPem.

Například pokud používáme LDAPS a nemáme správně certifikát či nepoužíváme TLS_REQCERT never (třeba když vůbec neexistuje ldap.conf), tak se v logu objeví následující chyba a neproběhne bind.

TLS certificate verification: Error, unable to get local issuer certificate
TLS trace: SSL3 alert write:fatal:unknown CA

Pokud nezapneme debug, tak se nedozvíme, proč se bind nepodařil.

zobrazeno: 32516krát | Komentáře [5]

Autor:

Související články:

Active Directory a protokol LDAP

Správa počítačové sítě ala Microsoft, to je Active Directory. Jedná se o velice rozsáhlou skupinu technologií a služeb. Základem jsou adresářové služby, adresáře a komunikační protokol LDAP.

Pokud se chcete vyjádřit k tomuto článku, využijte komentáře níže.

Komentáře

  1. [1] B0biN

    Pekny clanek, diky za nej ;-)

    Sobota, 03.11.2007 16:36 | odpovědět
  2. [2] LaYosH

    Pekne clanky, ale nerozumim tomuto:

    3.Musíme mít zprovozněné LDAPS na adresářovém serveru, takže AD server musí mít certifikát.

    a pak kdyz pouziji:

    "TLS_REQCERT never"

    tak ctu "nekontroluje se certifikát serveru"

    To znamena, ze AD server nemusi mit certifikat pri tomto nastaveni?

    Pondělí, 15.09.2008 19:52 | odpovědět
  3. [3] Samuraj

    odpověď na [2]LaYosH: Aby mohla být komunikace šifrovaný (při SSL nebo TLS) tak se využívá certifikát a jeho klíč. Takže vždy tam ten certifikát musí být.

    Druhá věc je, že certifikát se dá použít i k ověření, že server je opravdu ten, za který se vydává. To se provádí na straně klienta, ale tuto kontrolu nemusím použít.

    Pátek, 19.09.2008 15:11 | odpovědět
  4. [4] Otto

    Ahoj,

    řeším také tento problém.

    Mám XAMPP, kde SSL funguje (https://localhost běží).

    Ale když se zkusím připojit na ldaps, tak dostanu přesně tu chybu, která je zmíněná na konci textu.

    Žádný z návodů, které jsem našel nezabral.

    Neví někdo, co s tím? (případně: otto.kovarik@gmail.com)

    Středa, 05.06.2013 21:53 | odpovědět
  5. [5] JeLiTo

    Díky, to je super článek. S Active Directory všeobecně jsem se pral hrozně dlouhou dobu než sem na je nějak "zdolal":-) Jinak PHP mi přijde jako jeden z nejlepších jazyků, nejen srozumitelně, ale i v rámci nějakýho uplatnění. A nejlépe uplatnění v cizině. Zkoušel jsem najít nějaké weby, které se tím specializují, nevíte nějaké osvědčené? Mě říkal kámoš o itprace-nemecko.cz/,prý mu tam sehnali nějakou brigádu, akorát jsem se ještě nedostal k tomu, abych tam napsal životopis... :D (snad neva ten odkaz, nemyslel jsem to jako spam, spíš jestli s touhle konkrétní firmou má někdo nějaké zkušenosti)

    Pondělí, 18.11.2013 20:58 | odpovědět
Přidat komentář

Vložit tag: strong em link

Vložit smajlík: :-) ;-) :-( :-O

Nápověda:
  • maximální délka komentáře je 2000 znaků
  • HTML tagy nejsou povoleny (budou odstraněny), použít se mohou pouze speciální tagy (jsou uvedeny nad vstupním polem)
  • nový řádek (ENTER) ukončí odstavec a začne nový
  • pokud odpovídáte na jiný komentář, vložte na začátek odstavce (řádku) číslo komentáře v hranatých závorkách