This article builds on the theoretical introduction in the articles Directory Services and LDAP and LDAP Authentication (AD). And practical examples of using LDAP in How to use LDAP and LDAPS in PHP under Windows. It practically deals with the possibility of authenticating users against Active Directory using code in PHP.
As mentioned in the article on authentication in LDAP, we can use the LDAP protocol and its bind operation in practice for user authentication. Another option would be some external service, such as a RADIUS server. Using LDAP bind, we have two options, either simple bind or SASL bind.
Simple Bind
The simplest method, but also the least secure, is the use of simple bind. In this case, all (authentication) data is transmitted in plain text, i.e., in clear and unencrypted text. We send the username to the directory services in the form of DN (Distinguished Name), e.g., CN=User,OU=Users,DC=company,DC=local. In practice, I have verified that for Active Directory, the name can also be used in the UPN (User Principal Name) form, i.e., user@company.local, or in the form domain\username.
Since the password is sent in plain text, it is definitely recommended to use transmission over an encrypted channel. We can use SSL or TLS. I use SSL and therefore LDAPS.
Note: An important warning is that we need to check whether the user did not enter an empty password, because AD would then consider it an anonymous login and return true.
function authUserAD($username, $password, $DomainName="company.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("user", "Password")) echo "<p>Login is OK.</p>";
else echo "<p>Login failed.</p>";
SASL Bind
According to the notes on the LDAP functions, PHP supports SASL. It requires that PHP be compiled with SASL support and requires the libeay32.dll, ssleay32.dll (and possibly libsasl.dll) libraries. PHP version 5 contains the (essentially undocumented) ldap_sasl_bind function. However, I was unable to get it working, I did not acquire a Windows version of PHP with SASL support.
Other Options
Another option is to use a module for the Apache server (or use IIS). Additionally, these modules often allow the use of SSO (Single Sign On), if the client supports it.
- 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?
respond to [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??
respond to [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.
respond to [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...