ChatGPT解决这个技术问题 Extra ChatGPT

Authenticating in PHP using LDAP through Active Directory

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.

I thinks drupal has a module for thatr

c
ceejayoz

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
}

Some installations of AD will bind successfully if the password provided is empty. Watch out for this! You may need to ensure a non-empty password before trying to authenticate.
@diolemo Is there any way to prevent this without checking if the password is empty?
@Neal You may be able to use ldap_set_option to make it behave in a different way. Perhaps setting the protocol version? You will have to experiment. I would personally suggest you check for an empty password anyway, just to be safe.
To the anonymous editor: no, to my knowledge, input sanitization isn't required here as ldap_bind would be handling it and special characters aren't an issue.
C
ChadSikorra

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.


For LDAP connections, TLS has been deprecated in favor of StartTLS: openldap.org/faq/data/cache/605.html.
@zenlord Using the ldaps:// format for the connection is deprecated. In my example, when you specify setUseTls(true) it uses ldap:// format and then issues a StartTLS using ldap_start_tls($connection). So TLS itself hasn't been deprecated, just connecting using ldaps:// (which actually connects to LDAP over a completely different port).
S
Scott Reynen

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.


1
1234567

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


I went through the trouble of implementing the above to find that was for managing not authenticating. I intend to switch to zend.auth.adapter.ldap
D
Darryl Hein

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.


J
Joe Meyer

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.