plugin-LoginLdap icon indicating copy to clipboard operation
plugin-LoginLdap copied to clipboard

adding multiple LDAP servers, but only first one is used

Open rkaltreider opened this issue 8 years ago • 1 comments

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.

rkaltreider avatar May 05 '16 18:05 rkaltreider

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

rkaltreider avatar May 10 '16 15:05 rkaltreider