logo
Apache Lounge
Webmasters

 


About

Forum Index Downloads Search Register Log in  RSS Apache Lounge
 



Keep Server Online

If you find the Apache Lounge, the downloads and overall help useful, please express your satisfaction with a donation.

or

Bitcoin

A donation makes a contribution towards the costs, the time and effort that's going in this site and building.

Thank You! Steffen

Apache Lounge is not sponsored.

Your donations will help to keep this site alive and well, and continuing building binaries.



PHP Authenticate against Active Directory

 
Post new topic   Reply to topic    Apache Forum Index -> Coding & Scripting Corner



View previous topic :: View next topic  
Author Message
Brian



Joined: 21 Oct 2005
Posts: 209
Location: Puyallup, WA USA

PostPosted: Thu 10 Jan '08 23:52    Post subject: PHP Authenticate against Active Directory Reply with quote

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: 6255
Location: Germany, Next to Hamburg

PostPosted: Fri 11 Jan '08 10:47    Post subject: Reply with quote

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

PostPosted: Tue 29 Jan '08 20:48    Post subject: Reply with quote

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


Post new topic   Reply to topic    Apache Forum Index -> Coding & Scripting Corner
Page 1 of 1