Friday, October 1, 2010

Use PHP to perform an LDAP Bind to Windows Active Directory for User Authentication

This example shows some basic LDAP bind lookups on a Windows 2003 active directory server.

The sequence is:

  • Connect 
  • Bind using privileged user 
  • search for 'dn' of supplied credentials
  • re-bind using this dn and password of supplied credentials
  • unbind

The per-requisite is that php_ldap modules are loaded and compiled.  These are fairly standard now days.  In fedora it was just a matter of executing:



# yum install php-ldap

Anyway:  Here is the example.  It's farily well commented so should be a simple matter to make work in your own environment.



<?php
// example.php
//
// David Latham @ 2010
// david-latham.blogspot.com
//
// This code cannot be executed on the same server as AD is installed on!!!
//
// Active Directory has an Organizational Unit of "_Test_Users" with 3 users loaded
// into it.
// user1 | User One
// user2 | User Two
// ldapbind | ldap bind
//
// execute with php -q example.php

// credentials to test
$user='user2@example.local';
// user='user2'; //Use this one to test binding without an email address.
$pass='2wsx#EDC';

// AD server details
$ldap_server = "192.168.122.231";
$dn = "OU=_Test_Users,DC=example,DC=local";

// Connect
$ad = ldap_connect($ldap_server); //Must be a real active directory server
//(WIN2003 used in this example)

// Set some variables
ldap_set_option($ad, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ad, LDAP_OPT_REFERRALS, 0);

// Bind to the ldap directory.
// Here we are binding using a fixed user who has privileges to bind to the
// active directory. This user also has a fixed password. It can not change
// otherwise this script will break.


$bd = @ldap_bind($ad,"ldap user","pa$$word")
or die("Couldn't bind to AD!");

// Search the directory for a distinguished name (dn) using the supplied
// credentials.
//
// If $user is an email address then use 'mail' otherwise use 'sAMAccountName'

if( strpos($user, '@') > 0 ) {
$field='mail';
} else {
$field='sAMAccountName';
}
echo "Searching AD using ...".$field."\n";

$result = @ldap_search($ad, $dn, "(".$field."=".$user.")", array('dn'));

// Create result set
$entries = @ldap_get_entries($ad, $result);

// Show an array of result
print_r($entries);

// If we have a result then we should 're-bind' using the destinguished name found
// in the search.
if ( $entries[0] ) {
if(@ldap_bind($ad, $entries[0]['dn'], $pass)) {
// If bind was successful then show some data. This is user
// authentication success.
echo "found: ".$entries[0]['dn'];
} else {
// Bind failed so this would equate to user authentication failure.
echo "Failed to bind.";
}
} else {
// Failure to search would indicate a problem with your $dn variable.
echo "failed to search";
}

//never forget to unbind!
ldap_unbind($ad);

?>

the result might look something like this:



[dave@fedora php-ldap]$ php -q example.php
Searching AD using ...mail
Array
(
[count] => 1
[0] => Array
(
[count] => 0
[dn] => CN=user2,OU=_Test_Users,DC=example,DC=local
)

)
found: CN=user2,OU=_Test_Users,DC=example,DC=local

Have fun authenticating your users against your work active directory. You will:

  • Please your security manager

  • Avoid the headache of managing passwords password compliance

  • Write safer applications in terms of locking them down

  • Feel good about yourself

Post a Comment