Authenticate users against Azure Active Directory from PHP web application - php

I have a website in PHP and want to authentificate users against Azure Active Directory. With ldap_connect and bind I have no problems to do this to a local AD-Server in our company.
function checkADAccount($username, $password)
{
$adServer = "myADServer";
$ldaprdn = 'myDomain' . "\\" . $username;
$ldap = ldap_connect($adServer);
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
$bind = #ldap_bind($ldap, $ldaprdn, $password);
if ($bind) {
#ldap_close($ldap); // Verbindung schließen
return true;
} else {
return false;
}
}
But my application is hosted at Amazon Web Services (AWS) and is not in the same domain, so I can't use this way.
With ldap_connect and bind this functions to a local AD-Server in our company. But my application is hosted at Amazon Web Services (AWS) and is not in the same domain, so I can't use this way.
I tested graphapi with the ClientId and key for my company from Azure. So I can read the users-data, but I don't see any possibility to check a user/password combination. I only want to check, if there exists a user with this password, I don't need to read it from there.
So I tried to modify the LDAP-solution from above by changing the parameter of the adServer and of the user
$ldaprdn = 'sAMAccountname=' . $username . ',cn=users' . ',dc=myDomain,dc=com';
But I allwaws get: "Warning: ldap_bind(): Unable to bind to server: Can't contact LDAP server ". I tried for this multiple versions for the adServer but any delievers a binding.
Do you have any idea where is the error. I suggest with ldap_connect is the wron way, espacially I don't know which server-adress is the right one and how I had to tell the ClientId and key.

Currently, Azure AD doesn't support LDAP connection. It provides OAuth2 authentication and authorization. You can refer to Authentication Scenarios for Azure AD for detailed Azure AD scenarios.
For your requirement to authenticate users in your domain, you can leverage this code sample to implement authentication via Azure AD.
Otherwise, you can follow Authorization Code Grant Flow build your custom code to authenticate your users.
Any further concern, please feel free to let me know.

Related

Spring Security LDAP "bind must be completed on the connection"

I need to create a SpringBoot service and provide an authentication service using LDAP.
I followed this example and it works fine for me using an embedded local ldap server (as suggested into the tutorial)
Now I tried to use the official company LDAP server but I got this error:
Uncategorized exception occured during LDAP processing; nested exception is javax.naming.NamingException: [LDAP: error code 1 - 000004DC: LdapErr: DSID-0C090A5C, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v4563];
This error seems related to a LDAP bind request that it's necessary. But how can I add this into the Spring Security LDAP?
This is the code where I tried to integrate the company LDAP connection:
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.userDnPatterns("userPrincipalName={0},ou=users")
.groupSearchBase("ou=users")
.contextSource()
.url("ldap://companyhost:389/dc=aa,dc=company,dc=com")
.and()
.passwordCompare()
.passwordEncoder(new BCryptPasswordEncoder())
.passwordAttribute("userPassword");
}
I tried also with my PHP example (using the official company active directory and this works fine)
// connect to ldap server
$ad = ldap_connect("ldap://".LDAP_HOST, LDAP_PORT)
or die("Could not connect to LDAP server.");
ldap_set_option($ad, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ad, LDAP_OPT_REFERRALS, 0);
$user = $_POST['username'];
$password = $_POST['password'];
if (ldap_bind($ad, "$user"."#".LDAP_HOST, $password)) {
// User authenticated
}
The Directory Server you are connecting to does not allow 'anonymous' access, i.e. your application first has to authenticate beforehand (via and LDAP BIND operation) before performing queries. LdapContextSource
Furthermore Using password comparision ('passwordCompare()') is not LDAP best practice (I don't know why this is still in the Spring docs), itstead an LDAP BIND operation should be used to authenticate users. This lets the server compare the password as only the server knows which password storage scheme was used on the server side when the password was saved.
Using 'userDnPattern' is also not LDAP best practices as this means you have to know the Directory Information Tree (DIT) of the LDAP Directory Server. Instead let the Directory Server determine the Distinguished Name (DN) by performa search leveraging 'userSearchBase', 'userSearchFilter' LdapAuthenticationProviderConfigurer

Get notification on any updates performed on PHP LDAP Server

I have integrated PHP LDAP server on my server by following this guide. (Complete LDAP reference is here.)
I have displayed the users list which are available on LDAP server. Our application gets connected to many LDAP servers like one-many relationship, each user has LDAP server.
Now, I want my application to get a notification whenever there is a insert/update/delete (CRUD) operation performed on each user's LDAP server. I need Notifications for how many new records have been inserted/updated/deleted to LDAP server.
I have googled it but did not find any solution. I have a doubt, is this really possible to get notifications about any updates happened to LDAP server? If yes, can anyone please explain how to achieve this?
My code to LDAP connection & display users:
$domain = 'unixmen.local';
$username = 'cn=admin,dc=unixmen,dc=local';
$password = '****';
define('HOSTNAME','ldap://127.0.0.1');
$ldap_conn = ldap_connect(HOSTNAME,389) or die("Could not connect to ldap server");
ldap_set_option($ldap_conn, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldap_conn, LDAP_OPT_REFERRALS, 0);
$dn="ou=sales,dc=unixmen,dc=local";
$filter='(&(objectClass=inetOrgPerson)(uid=*))';
$result=ldap_search($ldap_conn, $dn, $filter, array("cn", "dn", "givenName", "uidNumber", "sn"));
for ($i=0; $i<$info["count"]; $i++)
{
$users[$i]["full_name"] = $info[$i]["cn"][0];
$users[$i]["first_name"] = $info[$i]["givenname"][0];
$users[$i]["last_name"] = $info[$i]["sn"][0];
$users[$i]["uid_number"] = $info[$i]["uidnumber"][0];
}
print_r($users);
There is an LDAP extension, that allows a server to notify a client application when entries are created, updated or deleted: LDAP Persistent Search control (https://datatracker.ietf.org/doc/html/draft-ietf-ldapext-psearch-03).
As the extension is not an approved standard, not all servers support it, and thus I don't think there is support for it in PHP.

Authenticate using LDAP

I have an ssh access to a LDAP server.
After accessing through ssh I can access to phpldapadmin. I have an admin DN and a password.
What needs to be done is I have to authenticate users using ldap whenever they try to login to a website.
Website is using jaggery for the server side code. But php is okay too.
I haven't worked with ldap and ssh. So if somebody can help on this I'll really appreciate it.
You have to download the adLDAP.php here:
http://adldap.sourceforge.net/download.php
Then the autentication is quiet simple:
$adldap = new adLDAP(array('base_dn'=>'DC=domainexample,DC=suffixexample', 'account_suffix'=>'#domainexample.suffix'));
$authUser = $adldap->authenticate('user', 'password');
if ($authUser == true) {
echo "User authenticated successfully<br>";
}
else {
echo "User authentication unsuccessful<br>";
}
You have only to be careful with the DC attribution: it depends on the LDAP network.
PHP has an extension to work with LDAP. You don't need to install third-party libraries.
Work with ldap and session is what you need.
http://us2.php.net/manual/pt_BR/book.ldap.php

PHP LDAP Connection to Authenticate against Active Directory from External Server

I have an external web server trying to authenticate against Active Directory on an internal server via LDAP. I am able to connect and authenticate locally, though using the same code (switching out host and port) am not able to authenticate externally. We have other services that are able to connect and authenticate such as Attask (http://www.attask.com/).
The external server is currently a Linux (gs) on Media Temple running PHP 5.3.15 with LDAP support enabled.
The internal server is currently a Windows Server 2008 box with LDAP and Active Directory.
The code below is the current PHP I am using that was able to connect locally, but having problems on the external server. It basically uses the PHP LDAP connection string and tries to bind. If it fails, it tries to bind anonymously. Both of which aren't working externally and returns the error: Can't contact LDAP server.
<?php
$username = 'username';
$password = 'password';
$ldapconfig['host'] = '00.000.000.000';
$ldapconfig['port'] = '636';
$ldapconfig['basedn'] = 'dc=client,dc=eqc,dc=local';
$ds=ldap_connect($ldapconfig['host'], $ldapconfig['port']);
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);
ldap_set_option($ds, LDAP_OPT_NETWORK_TIMEOUT, 10);
$dn="".$username."";
if ($bind=ldap_bind($ds, $dn, $password)) {
echo("Login correct");
} else {
echo("Unable to bind to server.</br>");
echo("msg:'".ldap_error($ds)."'</br>".ldap_errno($ds)."");
if ($bind=ldap_bind($ds)) {
$filter = "(cn=*)";
if (!($search=#ldap_search($ds, $ldapconfig['basedn'], $filter))) {
echo("Unable to search ldap server<br>");
echo("msg:'".ldap_error($ds)."'</br>");
} else {
$number_returned = ldap_count_entries($ds,$search);
$info = ldap_get_entries($ds, $search);
echo "The number of entries returned is ". $number_returned."<p>";
for ($i=0; $i<$info["count"]; $i++) {
var_dump($info[$i]);
}
}
} else {
echo("Unable to bind anonymously<br>");
echo("msg:".ldap_error($ds)."<br>");
}
}
?>
A few notes:
The external LDAP server is using LDAPS so the suggested host is ldaps://00.000.000.000 on port 636
I've tried binding with 'username' as well as 'username#00.000.000.000' already
There is a firewall, however, the external server can successfully ping the internal LDAP server so there is connection taking place on that level.
Any help would be greatly appreciated. If there are server settings or things of that nature, would love to know. Also, I've checked out ADFS though could not find a simple script to setup to test without spending a lot time to no end if it didn't work.
When connecting to AD using LDAPS from a Linux box, I've always had to add the line
TLS_REQCERT never
in /etc/ldap.conf or equivalent (might require an apache restart - not sure). You can also try the format "ldaps://server.domain.tld:636" for the host, though I don't think that's the issue.
I found some decent documentation at http://en.gentoo-wiki.com/wiki/Active_Directory_Authentication_using_LDAP, though it appears to be down at the moment. Google's cached version: http://webcache.googleusercontent.com/search?q=cache:http://en.gentoo-wiki.com/wiki/Active_Directory_Authentication_using_LDAP
Have you checked if it is an SSL certificate error? Are you using a self signed cert or an official one?
"If you're using SSL (e.g. ldaps) and ldap_bind is throwing 'Unable to bind to server:' errors, check that the hostname used in the ldap_connect matches the 'CN' in the SSL certificate on the LDAP server" Source

Connecting to a non-secure LDAP server via PHP on a Secure Domain

I am trying to connect to an ldap server that the client's IT guy says does not have an SSL certificate. This is on a test file on their domain, which has an SSL installed. Let's say the file is at https://client.org/test_LDAP.php
So I use very simple code to connect, which has worked fine with another client just in the past month:
ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);
define("LDAP_SERVER","ldap://name.their.junk");
define("LDAP_BASE","CN=Users,DC=their,DC=junk");
$username = 'CN=Username,'.LDAP_BASE;
$password = "Password";
$ldap = ldap_connect(LDAP_SERVER, 389) or die("Can't connect to LDAP server");
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3) ;
if (ldap_bind($ldap, $username, $password)) {
ldap_unbind($ldap);
echo 'OK - Login valid';
} else {
die(ldap_error($ldap) . ' (' . ldap_errno($ldap) . ')');
}
If I am running code from a domain with an SSL installed, does that mean I HAVE to use ldaps and port 636, even if the client's AD server doesn't have a Certificate? I've tried the code with both ports and both ldaps: and ldap: on an unsecured launch domain and also his secured live domain. Nothing seems to work. But he swears the username and password and all of the variables are correct, and told me to use their IP instaed of the hostname (ldap:000.000.000.00 for example).
Am I doing something wrong here?
And yes, I DO have LDAP configured correctly on my server end, because we just were able to do this exact same thing with another client recently.
Any insight would be much appreciated.
If you try to perform the searches on Windows 2003 Server Active Directory or above, it seems that you have to set the LDAP_OPT_REFERRALS option to 0:
ldap_connect(..)
ldap_set_option ($ldap, LDAP_OPT_REFERRALS, 0);
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_bind(..)

Categories