CZ 
06.10.2024 Hanuš VÍTEJTE V MÉM SVĚTĚ

An English translation is available for this article. Pro tento článek je dostupný anglický překlad.
User authentication against AD in PHP

Autentizace uživatele vůči AD v PHP

| Petr Bouška - Samuraj |
Tento článek navazuje na minulé ukázky použití LDAPu v PHP. Jednou užitečnou vlastností, kterou nám přináší přístup přes LDAP k adresářovým službám, je možnost provedení autentizace uživatele. V praxi tak můžeme, třeba na intranetu, autentizovat uživatele jeho doménovým účtem proti Active Directory. Článek ukazuje jednoduchý příklad, jak to provést. Samozřejmě lepší by ještě bylo využití Single Sign On, ale to již není tak jednoduché.
zobrazeno: 23 149x (23 144 CZ, 5 EN) | Komentáře [8]

Článek navazuje na teoretický úvod Adresářové služby a LDAP a Autentizace v LDAPu (AD). A praktické ukázky použití LDAPu v Jak na LDAP a LDAPS v PHP pod Windows. Věnuje se prakticky možnosti, jak autentizovat uživatele vůči Active Directory pomocí kódu v PHP.

Jak bylo zmíněno v článku o autentizaci v LDAPu, tak pro autentizaci uživatele můžeme v praxi použít právě protokol LDAP a jeho operaci bind. Jinou možností by byla nějaká externí služba, například RADIUS server. Pomocí LDAP bind máme dvě možnosti, buďto simple bind nebo SASL bind.

Simple bind

Nejjednodušší metoda, ale také nejméně bezpečná, je použití simple bind. V tomto případě se veškerá (autentizační) data přenáší v plain textu, tedy čistém a nešifrovaném textu. Adresářovým službám zasíláme uživatelské jméno ve tvaru DN (Distinguished Name), tedy třeba CN=Uzivatel,OU=Users,DC=firma,DC=local. V praxi jsem ověřil, že pro Active Directory je možno použít jméno i v UPN tvaru (User Principal Name) , tedy uzivatel@firma.local, nebo ve tvaru doména\uživatelské jméno.

Protože se heslo posílá v čistém textu, tak se určitě doporučuje použít přenos přes šifrovaný kanál. Můžeme použít SSL nebo TLS. Já používám SSL a tedy LDAPS.

Pozn.: Důležité upozornění je, že je třeba kontrolovat, zda uživatel nezadal prázdné heslo, protože AD by pak uvažovalo anonymní přihlášení a vrátilo by true.

function authUserAD($username, $password, $DomainName="firma.local", $ldap_server="ldaps://192.168.0.1") { 
  $auth_user = $username."@".$DomainName;
  if($connect = ldap_connect($ldap_server)){
    ldap_set_option($connect, LDAP_OPT_PROTOCOL_VERSION, 3);
    ldap_set_option($connect, LDAP_OPT_REFERRALS, 0);
    if(ldap_bind($connect, $auth_user, $password)) {
      ldap_close($connect);
      return(true);
    }
  }
  ldap_close($connect);
  return(false);
}
if(authUserAD("uzivatel", "Heslo")) echo "<p>Přihlášení je OK.</p>";
else echo "<p>Přihlášení se nezdařilo.</p>";

SASL bind

Podle poznámek u LDAP funkcí, PHP podporuje SASL. Je potřeba, aby bylo PHP zkompilováno s podporou SASL a vyžaduje knihovny libeay32.dll, ssleay32.dll (případně ještě libsasl.dll). PHP verze 5 obsahuje funkci (v podstatě nedokumentovanou) ldap_sasl_bind. Tu se mi však nepodařilo rozchodit, nezískal jsem pro Windows verzi PHP se SASL podporou.

Další možnosti

Jinou možností je využít nějaký modul pro Apache server (nebo použít IIS). Navíc tyto moduly většinou umožňují využít SSO (Single Sign On), pokud to podporuje klient.

  • mod_ntlm
  • mod_ntlm2
  • mod_auth_ntlm_winbind
  • mod_auth_sspi
  • mod_auth_gssapi
  • kerb_auth_mod
  • mod_auth_kerb

Související články:

Active Directory a protokol LDAP

Správa firemní počítačové sítě využívající Microsoft OS většinou znamená správu Active Directory Domain Services (AD DS). Jedná se o velice rozsáhlou skupinu technologií, protokolů a služeb. Základem jsou adresářové služby, autentizace 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] Jozef

    Da sa zistit aky uzivatel je prihlaseny, resp. zistit nie zadavat premennu $username?

    Středa, 03.11.2010 14:24 | odpovědět
  2. [2] Samuraj

    odpověď na [1]Jozef: Moc nechápu dotaz. Řešíme autentizaci, takže jako vždy si musíme údaj uložit (jaký username se přihlašuje) a nastavit si session proměnou o stavu přihlášení.

    Středa, 03.11.2010 15:14 | odpovědět
  3. [3] Jozef

    Vlastne nejde o autentifikaciu, ale zistenie uzivatela a podla toho pouzivat LDAP. Ci neexistuje premenna pre prihlaseneho uzivatela ako napr. $REMOTE_ADDR pre ip adresu.

    Čtvrtek, 04.11.2010 10:12 | odpovědět
  4. [4] Vlada

    Neměla by být místo proměnné $ds proměnná $connect??

    Čtvrtek, 02.12.2010 11:57 | odpovědět
  5. [5] Samuraj

    odpověď na [4]Vlada: Ano správně. Přepisoval jsem to ze svých zdrojáků a upravoval pro lepší pochopení, tohle jsem přehlédl.

    Čtvrtek, 02.12.2010 12:28 | odpovědět
  6. [6] Vlada

    OK díky, i tak je to skvělý návod jak na to...

    Čtvrtek, 02.12.2010 15:36 | odpovědět
  7. [7] Jozef

    Aha, mal som pozriet clanok: Kerberos SSO v PHP aplikaci s Apachem na Linuxu.

    Čtvrtek, 09.12.2010 14:28 | odpovědět
  8. [8] Diego

    odpověď na [3]Jozef: pomocí remote addr zjistit IP a pak příkaz nbtstat -a $ip (v php spustit nbtstat pomoci "system"). Na XP fungovalo spolehlive pokud je uzivatel prihlaseny v domene na jednom stroji. Dalsi moznost je utilita psloggedon.exe od psutils. musi bezet pod adm uctem a rozpozna uzivatele na vice PC. Na win 7 to slo taky, ale zalezi na nastaveni domenove politiky a jelikoz se casto meni tak po 3 letech opoustim tato reseni a hledam neco spolehlivejsiho. Asi to IIS...

    Pondělí, 30.05.2011 07:46 | 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