plugin-LoginLdap
plugin-LoginLdap copied to clipboard
adding multiple LDAP servers, but only first one is used
In my LDAP configuration I specify 3 different servers, which have different users based on their location. The first server in the list is a NA server. When a NA user attempts to login, they are successfully authenticated. The second server is EUR. When a EUR user tries to login, they are denied. I have verified the user exists and can successfully authenticate in other systems. It appears since they are not found in server1, and exception is thrown and the others servers are not queried.
Here is what I did to allow all servers in the list to be used to find a user. When the user is found, the loop is broken. Hope this helps someone else.
public function authenticate($username, $password, $alreadyAuthenticated = false)
{
$this->logger->debug(self::FUNCTION_START_LOG_MESSAGE, array(
'function' => __FUNCTION__,
'params' => array($username, "<password[length=" . strlen($password) . "]>", $alreadyAuthenticated)
));
if (empty($username)) {
throw new InvalidArgumentException('No username supplied in Model\\LdapUsers::authenticate().');
}
// if password is empty, avoid connecting to the LDAP server
if (empty($password)
&& !$alreadyAuthenticated
) {
$this->logger->debug("LdapUsers::{function}: empty password, skipping authentication", array(
'function' => __FUNCTION__
));
return null;
}
$ldapClientClass = $this->ldapClientClass;
$this->ldapClient = is_string($ldapClientClass) ? new $ldapClientClass() : $ldapClientClass;
$result = null;
foreach ($this->ldapServers as $server) {
try {
$this->ldapClient->connect($server->getServerHostname(), $server->getServerPort(), $this->getLdapNetworkTimeout());
$this->currentServerInfo = $server;
$this->logger->info("LdapUsers::{function}: Using LDAP server {host}:{port}", array(
'function' => __FUNCTION__,
'host' => $server->getServerHostname(),
'port' => $server->getServerPort()
));
$authenticationRequiredMemberOf = $this->authenticationRequiredMemberOf;
$logger = $this->logger;
$result = $this->doWithClient(function (LdapUsers $self, LdapClient $ldapClient)
use ($username, $password, $alreadyAuthenticated, $authenticationRequiredMemberOf, $logger) {
$user = $self->getUser($username, $ldapClient);
if (empty($user)) {
$logger->debug("LdapUsers::{function}: No such user '{user}' or user is not a member of '{group}'.", array(
'function' => __FUNCTION__,
'user' => $username,
'group' => $authenticationRequiredMemberOf
));
return null;
}
if ($alreadyAuthenticated) {
$logger->debug("LdapUsers::{function}: assuming user {user} already authenticated, skipping LDAP authentication", array(
'function' => __FUNCTION__,
'user' => $username
));
return $user;
}
if (empty($user['dn'])) {
$logger->debug("LdapUsers::{function}: LDAP user info for '{user}' has no dn attribute! (info = {info})", array(
'function' => __FUNCTION__,
'user' => $username,
'info' => array_keys($user)
));
return null;
}
if ($ldapClient->bind($user['dn'], $password)) {
return $user;
} else {
return null;
}
});
if($result !== null) {
break;
}
} catch (Exception $ex) {
$this->logger->debug("LDAP authentication failure: {message}", array('message' => $ex->getMessage(), 'exception' => $ex));
$result = null;
$this->logger->info("Model\\LdapUsers::{function}: Could not connect to LDAP server {host}:{port}: {message}", array(
'function' => __FUNCTION__,
'host' => $server->getServerHostname(),
'post' => $server->getServerPort(),
'message' => $ex->getMessage(),
'exception' => $ex
));
}
}
$this->logger->debug(self::FUNCTION_END_LOG_MESSAGE, array(
'function' => __FUNCTION__,
'result' => $result === null ? 'null' : array_keys($result)
));
return $result;
}