1. Обзор
В этом руководстве мы собираемся создать приложение CLI для проверки соединений с любым сервером аутентификации LDAP . Мы не будем использовать LDAP для защиты нашего приложения , так как это можно сделать лучше, используя , например, Spring Security LDAP .
Наличие инструмента для быстрой проверки правильности соединений LDAP полезно еще до разработки приложений, которые их используют. Это также полезно при разработке какой-либо интеграции между приложениями, особенно на этапе установки. И мы сделаем это, используя основные классы Java. Так что никаких дополнительных зависимостей не требуется .
2. Java-клиент LDAP
Начнем с создания нашего единственного класса LdapConnectionTool
. Начнем с основного
метода. Для простоты вся наша логика будет здесь:
public class LdapConnectionTool {
public static void main(String[] args) {
// ...
}
}
Во-первых, мы передадим наши параметры как системные свойства . Мы будем использовать значения по умолчанию для переменных factory
( LdapCtxFactory)
и authType
( simple
). LdapCtxFactory
— это основной класс Java, отвечающий за весь процесс подключения к серверу и заполнения пользовательских атрибутов. А простой
тип аутентификации означает, что наш пароль будет отправлен в виде открытого текста. Точно так же мы установим по умолчанию переменную запроса для
пользователя,
поэтому мы можем указать либо одну, либо обе. Мы увидим подробности использования позже:
String factory = System.getProperty("factory", "com.sun.jndi.ldap.LdapCtxFactory");
String authType = System.getProperty("authType", "simple");
String url = System.getProperty("url");
String user = System.getProperty("user");
String password = System.getProperty("password");
String query = System.getProperty("query", user);
Далее мы собираемся создать нашу карту окружения, которая содержит все свойства, необходимые для подключения, используя InitialDirContext
:
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, factory);
env.put(Context.SECURITY_AUTHENTICATION, authType);
env.put(Context.PROVIDER_URL, url);
Мы не хотим запрашивать пользователя и пароль, потому что некоторые серверы разрешают анонимный доступ :
if (user != null) {
env.put(Context.SECURITY_PRINCIPAL, user);
env.put(Context.SECURITY_CREDENTIALS, password);
}
При тестировании соединений мы часто передаем неверный URL-адрес или сервер просто не отвечает. Поскольку поведение клиента по умолчанию блокируется на неопределенный срок, пока не будет получен ответ, мы определим параметры тайм-аута . Время ожидания определяется в миллисекундах:
env.put("com.sun.jndi.ldap.read.timeout", "5000");
env.put("com.sun.jndi.ldap.connect.timeout", "5000");
После этого мы пытаемся установить соединение с новым экземпляром InitialDirContext
вместе с базовой обработкой исключений. Это важно, так как мы будем использовать его для диагностики распространенных проблем. Аналогичным образом, поскольку мы разрабатываем приложение CLI, мы выводим наши сообщения на стандартный вывод:
DirContext context = null;
try {
context = new InitialDirContext(env);
System.out.println("success");
// ...
} catch (NamingException e) {
System.out.println(e.getMessage());
} finally {
context.close();
}
Наконец, мы используем нашу переменную контекста
для запроса всех атрибутов, полученных в результате нашего необязательного запроса
:
if (query != null) {
Attributes attributes = context.getAttributes(query);
NamingEnumeration<? extends Attribute> all = attributes.getAll();
while (all.hasMoreElements()) {
Attribute next = all.next();
String key = next.getID();
Object value = next.get();
System.out.println(key + "=" + value);
}
}
3. Распространенные ошибки
В этом разделе мы рассмотрим некоторые распространенные ошибки и сообщения об ошибках, возникающие при попытке подключения к серверу:
- Неверный базовый DN: мы получим «код ошибки 49 — неверные учетные данные», если не настроим базовый DN должным образом. Поскольку каждый сервер имеет свою собственную структуру, мы всегда должны проверять ее в первую очередь, так как это сообщение может ввести в заблуждение .
- Нет анонимных подключений: мы получим сообщение об ошибке «ERR_229 Не удается аутентифицировать пользователя», если мы не настроим наш сервер для разрешения анонимного доступа.
4. Использование
Теперь, когда мы все настроили, мы можем использовать наше приложение. Во-первых, давайте создадим его как jar , переименуем в ldap-connection-tool.jar,
а затем попробуем один из следующих примеров. Обратите внимание, что эти значения полностью зависят от конфигурации нашего сервера .
Подключение с пользователем и паролем:
java -cp ldap-connection-tool.jar \
-Durl=ldap://localhost:389 \
-Duser=uid=gauss,dc=foreach,dc=com \
-Dpassword=password \
com.foreach.jndi.ldap.connectionTool.LdapConnectionTool
Указание только URL-адреса сервера для быстрой проверки подключения:
java -cp ldap-connection-tool.jar \
-Durl=ldap://localhost:389 \
com.foreach.jndi.ldap.connectionTool.LdapConnectionTool
Кроме того, указав запрос
вместе с пользователем
и паролем
, мы можем подключиться к конкретному пользователю, но запросить для другого. Это полезно, если нам нужно подключиться как администратор, например, перед выполнением запроса. Точно так же, если мы подключаемся к пользователю с достаточными привилегиями, мы можем видеть защищенные атрибуты, такие как пароли .
Наконец, передача системных свойств в качестве входных данных удобна при работе с простыми параметрами. Но есть и более элегантные способы разработки CLI-приложений, например, Spring Shell . Мы должны использовать что-то подобное для чего-то более сложного.
5. Вывод
В этой статье мы создали приложение CLI, которое может подключаться к серверу LDAP и запускать тесты подключения. Также в юнит-тестах есть еще примеры использования приложений . И, как всегда, исходный код доступен на GitHub .