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

User avatar
fbrano
Veteran Member
Posts: 70
Joined: 2018-03-19 10:39
Location: Slovakia
Contact:

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 12495 times
ver 23.15 1484

pböttcher
AppGini Super Hero
AppGini Super Hero
Posts: 1635
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.
Any help offered comes with the best of intentions. Use it at your own risk. In any case, please make a backup of your existing environment before applying any changes.

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';

User avatar
fbrano
Veteran Member
Posts: 70
Joined: 2018-03-19 10:39
Location: Slovakia
Contact:

Re: Authenticate against Microsoft Directory (LDAP)

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

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

User avatar
fbrano
Veteran Member
Posts: 70
Joined: 2018-03-19 10:39
Location: Slovakia
Contact:

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?
ver 23.15 1484

pböttcher
AppGini Super Hero
AppGini Super Hero
Posts: 1635
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.
Any help offered comes with the best of intentions. Use it at your own risk. In any case, please make a backup of your existing environment before applying any changes.

User avatar
fbrano
Veteran Member
Posts: 70
Joined: 2018-03-19 10:39
Location: Slovakia
Contact:

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%.
ver 23.15 1484

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;
?>

User avatar
fbrano
Veteran Member
Posts: 70
Joined: 2018-03-19 10:39
Location: Slovakia
Contact:

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.
ver 23.15 1484

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

A Bindi
Veteran Member
Posts: 51
Joined: 2018-01-04 18:45

Re: Authenticate against Microsoft Directory (LDAP)

Post by A Bindi » 2019-06-13 15:08

I applied the uthinus logInMember() customizated funcion for LDAP authentication, and it works great !!!

Is there a method to preserve the new code stored in the logInMember() function, in case of a project regeneration (e.g. when a new table is added) ?

ALex.

User avatar
jsetzer
AppGini Super Hero
AppGini Super Hero
Posts: 1806
Joined: 2018-07-06 06:03
Location: Kiel, Germany
Contact:

Re: Authenticate against Microsoft Directory (LDAP)

Post by jsetzer » 2019-06-13 15:37

Would be great if we could have a hook for authentication.
Kind regards,
<js />

My AppGini Blog:
https://appgini.bizzworxx.de/blog

You can help us helping you:
Please always put code fragments inside [code]...[/code] blocks for better readability

AppGini 24.10 Revision 1579 + all AppGini Helper tools

A Bindi
Veteran Member
Posts: 51
Joined: 2018-01-04 18:45

Re: Authenticate against Microsoft Directory (LDAP)

Post by A Bindi » 2021-01-27 13:07

Hello,

I revamp this interesting post with a new question.

We have implemented for a long time the LDAP authentication (in according with the script documented in this post), so every time the
project was compiled we manually modified the incCommon.php replacing the logInMember() function with the LDAP-ready function and everything has always worked very well for years.

Unfortunately some days ago we moved form Appgini 5.82 to 5.94 and bought and installed the "Inline Detail-View Plugin" and "Appgini Helper Javascript Library" to enjoy all new features, but we noticed a problem.

Well, after the 5.94 upgrade the LDAP authentication seems to not function anymore and the login continues to ask for credentials with not access
permitted (no errors seems to appear); in the meantime we replaced the compiled pages with an old backup, but we would resolve the problem to use the new AppGini release.

Is it possible that in the last AppGini release something the logInMember() functioning is changed so the changes for LDAP stopped working ?

:(

ALex.

User avatar
jsetzer
AppGini Super Hero
AppGini Super Hero
Posts: 1806
Joined: 2018-07-06 06:03
Location: Kiel, Germany
Contact:

Re: Authenticate against Microsoft Directory (LDAP)

Post by jsetzer » 2021-03-12 08:23

... and installed the "Inline Detail-View Plugin" and "Appgini Helper Javascript Library" ...
Hi ALex,

only a marginal note: Neither the Inline Detail-View Plugin nor the AppGini Helper Javascript Library change the login procedure itself. But there are functions in the Javascript library which allow you to change the User Interface (UI) of the login form. If you had to change the login form for your LDAP hack, the problem may be just with the user interface. To narrow down the error, test removing the <script>-include from header-extras.php. If problem still occurs even without including the lib we can assume that the lib has nothing to do with the LDAP/Login problem.
Kind regards,
<js />

My AppGini Blog:
https://appgini.bizzworxx.de/blog

You can help us helping you:
Please always put code fragments inside [code]...[/code] blocks for better readability

AppGini 24.10 Revision 1579 + all AppGini Helper tools

User avatar
a.gneady
Site Admin
Posts: 1280
Joined: 2012-09-27 14:46
Contact:

Re: Authenticate against Microsoft Directory (LDAP)

Post by a.gneady » 2024-01-23 17:35

I'm glad to announce that we've just added LDAP support to AppGini 24.10, https://bigprof.com/appgini/help/ldap-authentication

All you need to do is configure LDAP settings from the admin area > Utilities menu > Admin settings > LDAP

You don't need to define your LDAP users first in your AppGini app. Instead, you can configure LDAP settings to automatically add new users to a specified group. May be you could give this group minimal or no permissions, review the users in there, and move them to other groups to activate them.
:idea: AppGini plugins to add more power to your apps:
  • DataTalk is an innovative AppGini plugin based on ChatGPT that allows you to interact with your AppGini database using natural language questions, without writing any SQL. Check the demo video
  • Mass Update plugin: Update multiple records at once and improve your workflow efficiency.
  • Check our other plugins and get a generous discount of up to 30% when buying 2 or more plugins.

tsmets
Posts: 3
Joined: 2023-11-27 09:15

Re: Authenticate against Microsoft Directory (LDAP)

Post by tsmets » 2024-01-24 20:46

Hello and thank you for the wonderful announcement.
We immediately downloaded and installed the latest version.
First of all, the positive thing is that we can connect to LDAP and can log in with Microsoft Active Directory users.
This finally gives us the necessary boost for integrated services and user-friendliness. Many thanks for the implementation.

What we haven't managed to do is to use another attribute than "cn" for the user names.
For example, if we take the classic sAMAccountName attribute for Windows logon, it doesn't work. Same with uid.

Since it works with "cn", I do not assume that we have configured the integration incorrectly. We have tried it with both upper and lower case.
Maybe a suggestion what the problem could be?
Unfortunately, we have first name and last name in the "cn" attribute for all users and not the classic user login name.

Many thanks in advance
Greetings
Thorsten

Post Reply