Keep Server Online
If you find the Apache Lounge, the downloads and overall help useful, please express your satisfaction with a donation.
or
A donation makes a contribution towards the costs, the time and effort that's going in this site and building.
Thank You! Steffen
Your donations will help to keep this site alive and well, and continuing building binaries. Apache Lounge is not sponsored.
| |
|
Topic: PHP Authenticate against Active Directory |
|
Author |
|
Brian
Joined: 21 Oct 2005 Posts: 209 Location: Puyallup, WA USA
|
Posted: Thu 10 Jan '08 23:52 Post subject: PHP Authenticate against Active Directory |
|
|
My test environment is a 2003 Domain in Native Mode.
Here is a hybrid of a script I found somewhere and some changes that I included to allow multiple logins, to eliminate the need to include the domain (i.e. domain\username at login) and since I have two domain controllers I included them as IP addresses, you could of course include as many as you like.
This is at this time a testing script but I plan to implement it to allow me to use AD to authenticate users to a new Intranet site I am working on. The only downside is that to create permissions for each user I still at this time must maintain a separate database such as MySQL for that. But in MySQL I don't need to worry about passwords for authentication, just a list of usernames and permission attributes.
Here is the testing code that worked for me, I would like to know if others find it useful:
Code: | <?php
error_reporting(1);
session_start();
function authenticate() {
header('WWW-Authenticate: Basic realm="Active Directory Login"');
header('HTTP/1.0 401 Unauthorized');
echo 'Sorry, you must login using the correct user and pass.';
echo '<br><br><a href="' . $PHP_SELF . '?logout=1">Click here</a> to try again.';
exit;
}
if(!isset($_SERVER['PHP_AUTH_USER']) || ($_GET['logout'] == 1 && isset($_SESSION['user']) && isset($_SESSION['domain']))){
session_unset();
authenticate();
} else {
$_SESSION["domain"] = $domain = 'MYDOMAIN'; // <- your domain
$_SESSION["user"] = strtoupper($_SERVER["PHP_AUTH_USER"]);
$_SESSION["password"] = $_SERVER["PHP_AUTH_PW"];
$LDAPServerAddress1="192.168.1.xxx"; // <- IP address for your 1st DC
$LDAPServerAddress2="192.168.1.xxx"; // <- IP address for your 2nd DC...and so on...
$LDAPServerPort="389";
$LDAPServerTimeOut ="60";
$LDAPContainer="dc=mydomain,dc=com"; // <- your domain info
$BIND_username = "mydomain\\authaccountuser"; // <- an account in AD to test using
$BIND_password = "authaccountpass";
$filter = "sAMAccountName=".$_SESSION["user"];
$login_error_code = 0;
if(($ds=ldap_connect($LDAPServerAddress1)) || ($ds=ldap_connect($LDAPServerAddress2))) {
ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
if($r=ldap_bind($ds,$BIND_username,$BIND_password)) {
if($sr=ldap_search($ds, $LDAPContainer, $filter, array('distinguishedName'))) {
if($info = ldap_get_entries($ds, $sr)) {
$BIND_username = $info[0]['distinguishedname'][0];
$BIND_password = $_SERVER["PHP_AUTH_PW"];
if ($r2=ldap_bind($ds,$BIND_username,$BIND_password)) {
if($sr2=ldap_search($ds, $LDAPContainer, $filter, array("givenName","sn","mail","displayName"))) {
if($info2 = ldap_get_entries($ds, $sr2)) {
$_SESSION["name"] = $info2[0]["givenname"][0]." ".$info2[0]["sn"][0];
$_SESSION["email"] = $info2[0]["mail"][0];
$_SESSION["displayname"] = $info2[0]["displayname"][0];
} else {
$login_error = "Could not read entries"; $login_error_code=1;
}
} else {
$login_error = "Could not search"; $login_error_code=2;
}
} else {
$login_error = "User password incorrect"; $login_error_code=3;
}
} else {
$login_error = "User name not found"; $login_error_code=4;
}
} else {
$login_error = "Could not search"; $login_error_code=5;
}
} else {
$login_error = "Could not bind"; $login_error_code=6;
}
} else {
$login_error = "Could not connect"; $login_error_code=7;
}
if($login_error_code > 0){
authenticate();
} else {
echo 'Welcome ' . $_SESSION["displayname"];
echo '<br><br><a href="' . $PHP_SELF . '?logout=1">Click here</a> to logout and try again.';
}
}
?> |
You need to provide the correct IP address(es) for your domain controller(s), the authentication user and pass (I found that just to authenticate any user account actually works), then you are in business.
What the original script did was it required you to enter the domain. It also did not offer any way to logout / relogin, this script handles this well.
Also, it does not authenticate any account that is disabled.
If anyone knows how you can ascertain "group" information about users, that is, what security groups is "joe" a member of, that would be simply awesome because then an administrator could create security groups in AD and utilize them in a PHP based web site. I have no idea how to do this at this time, or if it is even possible.
Please let me know if this script works for you or not. Thank you. |
|
Back to top |
|
James Blond Moderator
Joined: 19 Jan 2006 Posts: 7371 Location: Germany, Next to Hamburg
|
Posted: Fri 11 Jan '08 10:47 Post subject: |
|
|
I have some trouble against my Win 2000 Domain.
I can login with every also none existing user if I fill out user and password.
So I tried
Code: |
$BIND_username = $_SESSION["domain"]."\\".$_SESSION["user"];
$BIND_password = $_SERVER["PHP_AUTH_USER"];
|
With that I could not login at all. |
|
Back to top |
|
Brian
Joined: 21 Oct 2005 Posts: 209 Location: Puyallup, WA USA
|
Posted: Tue 29 Jan '08 20:48 Post subject: |
|
|
Sorry for the very delayed reply. I don't have a 2000 domain to test this within, all my controllers are 2003. I don't see why this would fail in a 2000 environment other than the LDAP connection is handled differently maybe?
Now if anyone has a way to test for GROUP membership that actually works, that would be very powerful. Then we could develop Intranet apps that work with Group Policy essentially.
Also for those trying this, you can do simple authentication using any active AD account, it does not have to be an admin level account. |
|
Back to top |
|
|
|
|
|
|