Authenticate against Microsoft Directory (LDAP)

Got something cool to share with AppGini users? Feel free to post it here!
Post Reply
User avatar
uthinus
Posts: 4
Joined: 2018-05-30 21:26
Location: Bloemfontein South Africa

Authenticate against Microsoft Directory (LDAP)

Post by uthinus » 2018-05-31 09:39

This is my contribution on how I authenticate against AD in my organisation
Note that this solution could be dependent on how AD has been setup in your organisation but the principals should be the same. I know that there are probably better ways and better coding to this but I am sharing with the hope that it could save fellow Appgini user some time.

First make sure that the php LDAP library is installed and available on your system. You can check this with phpinfo() Make a note of the were the php.ini file is located. If not activated or installed install it first install it.
In Centos do: yum install php-ldap
Add or uncomment in php.ini: extention=ldap.so
Restart your apache/http service: service httpd restart

Before you change code in Appgini run a test authentication program to ensure you have everything setup correctly.
For example:
<?php
$link = ldap_connect('FDC-DC01.FDC.LOCAL'); // Your domain or domain server
if(! $link) {
echo "Could not connect to server - handle error appropriately";
}
else {
echo 'Bind was successful</br>';
}
$ldap_username ='your login name';
$ldap_password = 'your password';

ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, 3); // Recommended for AD

// Now try to authenticate with credentials provided by user
if (ldap_bind($link, $ldap_username, $ldap_password)) {
echo 'User LDAP Authentication was successful<br>';
}
else{
echo 'Invalid credentials! Handle error appropriately</br>';
}
$unbind = ldap_unbind($link);
if ($unbind){
echo 'Unbind was successful !!</br>';
}
else {
echo 'unbind problem found</br>';
}
?>


Make sure that you have an admin user created in the Appgini user DB that also exist on the AD structure. If you do not do this you will not be able to login as an administrator on you Appgini system. The idea is that we will be creating a user in Appgini whose user name will be on AD and on the Appgini DB. The active directory password will not be stored in Appgini. The password and username supplied by the user will be used to authenticate against AD and if true we will check to see if the user exist in the Appgini DB.
The custom code changes will made in the IncCommon.php generated code. Look for the function logInMember().
I did not change the Appgini variable $username and $password but rather defined new ones for usage with LDAP
The $link variable is used to set the domain name and will be dependent on your environment
If the link to the domain was successful I check the user credential entered against the AD credentials. If it was successful the $ldap_authorized variable is set to true.
I encapsulated the rest of the Appgini code with an if statement. This means that if a user has valid AD credentials the “if (sqlValue…” will be done. Note that I removed the $password from the select statement as I do not have the AD password in the Appgini DB only the login name.

Changes made Incommon.php LoginMember()
#########################################################
// Set custom code in this function take out password selction form sql value
// test password entered against active directory
function logInMember(){
$redir = 'index.php';
if($_POST['signIn'] != ''){
if($_POST['username'] != '' && $_POST['password'] != ''){
$username = makeSafe(strtolower($_POST['username']));
$password = md5($_POST['password']);
$ldap_username = 'FDC\\'.$_POST['username']; //FDC\ is needed for the FDC ad depends on your ad setup
$ldap_password = $_POST['password'];
$link = ldap_connect('FDC-DC01.FDC.LOCAL'); // Your domain or domain server
if ($link){ // The bind to domain was sucessfull
ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, 3); // Recommended for AD
if (ldap_bind($link, $ldap_username, $ldap_password)) { // Now try to authenticate with credentials provided by user
$ldap_authorized = true;
$_POST['rememberMe']=0; // do not want to keep ad info in cookies
}
}
if ($ldap_authorized) { //if ldap_authorized carry on to see if registered in the program

//if(sqlValue("select count(1) from membership_users where lcase(memberID)='$username' and passMD5='$password' and isApproved=1 and isBanned=0")==1){
if(sqlValue("select count(1) from membership_users where lcase(memberID)='$username' and isApproved=1 and isBanned=0")==1){
$_SESSION['memberID']=$username;
$_SESSION['memberGroupID']=sqlValue("select groupID from membership_users where lcase(memberID)='$username'");
if($_POST['rememberMe']==1){
@setcookie('helpdesk_rememberMe', md5($username.$password), time()+86400*30);
}else{
@setcookie('helpdesk_rememberMe', '', time()-86400*30);
}

// hook: login_ok
if(function_exists('login_ok')){
$args=array();
if(!$redir=login_ok(getMemberInfo(), $args)){
$redir='index.php';
}
}

redirect($redir);
exit;
}
} //authorized ldap
}

// hook: login_failed
if(function_exists('login_failed')){
$args=array();
login_failed(array(
'username' => $_POST['username'],
'password' => $_POST['password'],
'IP' => $_SERVER['REMOTE_ADDR']
), $args);
}

if(!headers_sent()) header('HTTP/1.0 403 Forbidden');
redirect("index.php?loginFailed=1");
exit;
}elseif((!$_SESSION['memberID'] || $_SESSION['memberID']==$adminConfig['anonymousMember']) && $_COOKIE['helpdesk_rememberMe']!=''){
$chk=makeSafe($_COOKIE['helpdesk_rememberMe']);
if($username=sqlValue("select memberID from membership_users where convert(md5(concat(memberID, passMD5)), char)='$chk' and isBanned=0")){
$_SESSION['memberID']=$username;
$_SESSION['memberGroupID']=sqlValue("select groupID from membership_users where lcase(memberID)='$username'");
}
}
}

#########################################################


To summarize the steps, I followed:
Create a user in Appgini with the same username as in AD (password does not have to be the same as in AD)
Make custom changes to the function LogInMember()
Test the connection to AD
Test the login credential supplied against AD
If successful test if user exist in Appgini DB
If successful allow access to Appgini system

fbrano
Posts: 28
Joined: 2018-03-19 10:39

Re: Authenticate against Microsoft Directory (LDAP)

Post by fbrano » 2018-06-27 07:10

After testing php code I got error, any ideas?
LDAP test.JPG
LDAP test.JPG (53.17 KiB) Viewed 723 times

pböttcher
AppGini Super Hero
AppGini Super Hero
Posts: 263
Joined: 2018-04-01 10:12

Re: Authenticate against Microsoft Directory (LDAP)

Post by pböttcher » 2018-06-27 09:18

Hi,

did you use the correct credentials. As the error states "invalid credentials".
Also could you post your test_ldap.php. Otherwise it will be difficult to help.

User avatar
uthinus
Posts: 4
Joined: 2018-05-30 21:26
Location: Bloemfontein South Africa

Re: Authenticate against Microsoft Directory (LDAP)

Post by uthinus » 2018-07-10 14:47

Hi fbrano,

Like pböttcher say it would be better if we could see you code.

I am going to take a stab at it anyway because I had a similar problem and it was simple to fix.
On your windows machine that you use to login to your domain note the following:
When asked to type in your user name on Windows login screen type in your DOMAIN\USERNAME and not just USERNAME.

Once you have established that it works use the exact same syntax in the php test program
For example: $ldap_username ='domain\username';

fbrano
Posts: 28
Joined: 2018-03-19 10:39

Re: Authenticate against Microsoft Directory (LDAP)

Post by fbrano » 2018-08-21 06:08

Only with 'DOMAIN\login name' I got successful result.

fbrano
Posts: 28
Joined: 2018-03-19 10:39

Re: Authenticate against Microsoft Directory (LDAP)

Post by fbrano » 2018-08-21 11:59

LDAP authentication works, thank you.

Now I have to fill up membership_users db with all active directory accounts. Will I have to generate random passwords for imported AD users while appgini application has minimun 4 characters password condition when new user is created?

pböttcher
AppGini Super Hero
AppGini Super Hero
Posts: 263
Joined: 2018-04-01 10:12

Re: Authenticate against Microsoft Directory (LDAP)

Post by pböttcher » 2018-08-21 13:02

Hi,

no, you will authenticate the user against the LDAP, so the password set in AppGini is not relevant for those users any more.

fbrano
Posts: 28
Joined: 2018-03-19 10:39

Re: Authenticate against Microsoft Directory (LDAP)

Post by fbrano » 2018-08-22 11:37

I'd like to know your thinking on this. Is it possible to modify sign up dialog to remove password field, because it is confusing to check password complex to minimum 4 characters when it is not applicable during LDAP authentication?
How to force user to use his AD account as username? I came uppon a scenarios:
a) to store windows system variable %username% into appgini application sign up dialog variable username,
b) to compare imput value in username with system variable %username%.

User avatar
uthinus
Posts: 4
Joined: 2018-05-30 21:26
Location: Bloemfontein South Africa

Re: Authenticate against Microsoft Directory (LDAP)

Post by uthinus » 2018-08-31 13:01

Hi fbrano

I am not sure I understand why you want to remove the password field. The password variable content is used to verify against AD.
You are forcing a user to use his AD username because you have manfully created in Appgini when you are logged in as Administrator
They cannot use a user name that you have not already created.

In my view sing the local system variables to do something on the server side could be problematic. The local environment variables available will be dependent on things like your operating system, the browser you are using, the windows profile and the webserver running on the server.
Search for “php get windows authenticated user” in Google to see that it is possible but not guaranteed.

In my case I did not want to bypass the Appgini login because I still wanted to use the group and rights functionality without custom code. You can try the following in php to see what you get:
Run phpinfo() to see what variable have useful user information on your system
In my environment I can get the Windows login name with:

<?php
$uname = getenv('USERNAME');
echo $uname;
?>

fbrano
Posts: 28
Joined: 2018-03-19 10:39

Re: Authenticate against Microsoft Directory (LDAP)

Post by fbrano » 2018-09-06 16:06

Let me explain it, I do not want to remove it only hide it and of course not from sign in page but from sign up page.

I do not think that new user account in AppGini application is checked in LDAP during sign up process.

User avatar
uthinus
Posts: 4
Joined: 2018-05-30 21:26
Location: Bloemfontein South Africa

Re: Authenticate against Microsoft Directory (LDAP)

Post by uthinus » 2018-09-07 20:14

I disable signup for all groups and users in the admin area see https://forums.appgini.com/phpbb/viewto ... 544945d2a6

Post Reply