Č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
Da sa zistit aky uzivatel je prihlaseny, resp. zistit nie zadavat premennu $username?
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í.
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.
Neměla by být místo proměnné $ds proměnná $connect??
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.
OK díky, i tak je to skvělý návod jak na to...
Aha, mal som pozriet clanok: Kerberos SSO v PHP aplikaci s Apachem na Linuxu.
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...