Authenticating in PHP using LDAP through Active Directory

PhpAuthenticationActive DirectoryLdap

Php Problem Overview


I'm looking for a way to authenticate users through LDAP with PHP (with Active Directory being the provider). Ideally, it should be able to run on IIS 7 (adLDAP does it on Apache). Anyone had done anything similar, with success?

  • Edit: I'd prefer a library/class with code that's ready to go... It'd be silly to invent the wheel when someone has already done so.

Php Solutions


Solution 1 - Php

Importing a whole library seems inefficient when all you need is essentially two lines of code...

$ldap = ldap_connect("ldap.example.com");
if ($bind = ldap_bind($ldap, $_POST['username'], $_POST['password'])) {
  // log them in!
} else {
  // error message
}

Solution 2 - Php

You would think that simply authenticating a user in Active Directory would be a pretty simple process using LDAP in PHP without the need for a library. But there are a lot of things that can complicate it pretty fast:

  • You must validate input. An empty username/password would pass otherwise.
  • You should ensure the username/password is properly encoded when binding.
  • You should be encrypting the connection using TLS.
  • Using separate LDAP servers for redundancy in case one is down.
  • Getting an informative error message if authentication fails.

It's actually easier in most cases to use a LDAP library supporting the above. I ultimately ended up rolling my own library which handles all the above points: LdapTools (Well, not just for authentication, it can do much more). It can be used like the following:

use LdapTools\Configuration;
use LdapTools\DomainConfiguration;
use LdapTools\LdapManager;

$domain = (new DomainConfiguration('example.com'))
    ->setUsername('username') # A separate AD service account used by your app
    ->setPassword('password')
    ->setServers(['dc1', 'dc2', 'dc3'])
    ->setUseTls(true);
$config = new Configuration($domain);
$ldap = new LdapManager($config);

if (!$ldap->authenticate($username, $password, $message)) {
    echo "Error: $message";
} else {
    // Do something...
}

The authenticate call above will:

  • Validate that neither the username or password is empty.
  • Ensure the username/password is properly encoded (UTF-8 by default)
  • Try an alternate LDAP server in case one is down.
  • Encrypt the authentication request using TLS.
  • Provide additional information if it failed (ie. locked/disabled account, etc)

There are other libraries to do this too (Such as Adldap2). However, I felt compelled enough to provide some additional information as the most up-voted answer is actually a security risk to rely on with no input validation done and not using TLS.

Solution 3 - Php

I do this simply by passing the user credentials to ldap_bind().

http://php.net/manual/en/function.ldap-bind.php

If the account can bind to LDAP, it's valid; if it can't, it's not. If all you're doing is authentication (not account management), I don't see the need for a library.

Solution 4 - Php

I like the Zend_Ldap Class, you can use only this class in your project, without the Zend Framework.

Solution 5 - Php

PHP has libraries: http://ca.php.net/ldap

PEAR also has a number of packages: http://pear.php.net/search.php?q=ldap&in=packages&x=0&y=0

I haven't used either, but I was going to at one point and they seemed like they should work.

Solution 6 - Php

For those looking for a complete example check out http://www.exchangecore.com/blog/how-use-ldap-active-directory-authentication-php/.

I have tested this connecting to both Windows Server 2003 and Windows Server 2008 R2 domain controllers from a Windows Server 2003 Web Server (IIS6) and from a windows server 2012 enterprise running IIS 8.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDV.View Question on Stackoverflow
Solution 1 - PhpceejayozView Answer on Stackoverflow
Solution 2 - PhpChadSikorraView Answer on Stackoverflow
Solution 3 - PhpScott ReynenView Answer on Stackoverflow
Solution 4 - PhpChristian C. SalvadóView Answer on Stackoverflow
Solution 5 - PhpDarryl HeinView Answer on Stackoverflow
Solution 6 - PhpJoe MeyerView Answer on Stackoverflow