Мы — команда мобильных разработчиков с 5+ летним опытом интеграции корпоративных систем. Прямая LDAP-интеграция в мобильном приложении — почти всегда архитектурная ошибка: порты 389/636 закрыты за файрволом, LDAP-bind credentials нельзя хранить на устройстве, соединение через мобильный интернет к on-premise AD нестабильно. Правильная схема — backend-прокси: мобильный → backend API → AD/LDAP. Это гарантирует безопасность и масштабируемость. Мы реализуем интеграцию под ключ, используя современные протоколы и шифрование. Наши сертифицированные инженеры проведут аудит вашей инфраструктуры и предложат оптимальное решение. Закажите консультацию — оценим проект бесплатно.
Почему нельзя подключаться к LDAP напрямую с мобильного?
Мобильные сети непредсказуемы, а корпоративные LDAP-серверы находятся за строгим файрволом. При попытке прямого соединения вы столкнетесь с сетевыми блокировками, требованием открывать порты (что нарушает политики безопасности), и уязвимостью хранения учётных данных на устройстве. Даже при использовании VPN добавятся задержки и сложность управления. Backend-прокси решает эти проблемы: все соединения инициируются из защищенного сегмента сети, а мобильное приложение работает только через HTTPS с JWT.
Архитектура интеграции: backend-прокси
Backend выступает LDAP-прокси: принимает запросы от мобильного через HTTPS с JWT-авторизацией, обращается к AD/LDAP внутри корпоративной сети, возвращает данные в REST-формате.
Мобильный ──HTTPS/JWT──► Backend API ──LDAP 636──► Active Directory └──LDAP 389──► OpenLDAP Для аутентификации через AD на backend используем LDAP-bind:
// Node.js, ldapjs const client = ldap.createClient({ url: "ldaps://dc01.company.local:636", tlsOptions: { rejectUnauthorized: true, ca: [fs.readFileSync("ca.crt")] }, }); async function authenticateUser(username, password) { const userDN = `cn=${username},ou=Users,dc=company,dc=local`; return new Promise((resolve, reject) => { client.bind(userDN, password, (err) => { if (err) { reject(new InvalidCredentialsError()); } else { resolve(true); client.unbind(); } }); }); } После успешного bind backend генерирует JWT и возвращает на мобильный. Пароль пользователя никогда не покидает backend.
| Параметр | Прямой доступ | Backend-прокси |
|---|---|---|
| Безопасность | Низкая: пароль на устройстве | Высокая: пароль не хранится |
| Масштабируемость | Ограниченная: стабильность сети | Высокая: кэширование, балансировка |
| Скорость | Зависит от сети клиента | Оптимизирована на backend |
| Сложность внедрения | Простая, но опасная | Требуется разработка |
Как защитить учетные данные пользователей?
Пароль пользователя передается от мобильного на backend по HTTPS. Backend выполняет LDAP-bind — единственное место, где пароль используется. После подтверждения подлинности backend генерирует JWT с ограниченным сроком действия (например, 1 час). Мобильное устройство сохраняет только JWT, пароль нигде не кэшируется. При увольнении сотрудника аккаунт в AD деактивируется, backend при следующем refresh_token обнаруживает неудачный LDAP lookup и инвалидирует JWT — доступ немедленно блокируется.
Получение атрибутов пользователя
AD хранит богатый набор атрибутов: displayName, mail, telephoneNumber, department, manager, memberOf (группы), thumbnailPhoto (аватар). Для корпоративного приложения это ценный источник данных — не нужно дублировать профили пользователей.
async function getUserAttributes(username) { const base = "ou=Users,dc=company,dc=local"; const opts = { filter: `(sAMAccountName=${username})`, scope: "sub", attributes: [ "displayName", "mail", "department", "manager", "memberOf", "thumbnailPhoto", ], }; return new Promise((resolve, reject) => { client.search(base, opts, (err, res) => { let entry = null; res.on("searchEntry", (e) => (entry = e.object)); res.on("end", () => resolve(entry)); res.on("error", reject); }); }); } thumbnailPhoto — это JPEG в base64 прямо в AD. Возвращаем его как base64-строку или сохраняем в object storage и возвращаем URL.
memberOf содержит DN групп: CN=VPN-Users,OU=Groups,DC=company,DC=local. Группы определяют права пользователя в приложении — парсим CN из DN и маппим на application roles.
Как построить оргструктуру из AD?
AD содержит иерархию через атрибут manager (DN руководителя) и directReports. Построить дерево оргструктуры через рекурсивные LDAP-запросы — возможно, но медленно при глубоких иерархиях. Лучше: кэшировать структуру на backend с периодическим обновлением (раз в час/сутки), мобильный запрашивает готовый граф.
// Android — отображение оргструктуры data class OrgNode( val employeeId: String, val name: String, val position: String, val department: String, val avatarUrl: String?, val directReports: List<OrgNode> ) @Composable fun OrgChart(rootNode: OrgNode) { LazyColumn { item { EmployeeCard(node = rootNode, level = 0) } items(rootNode.directReports) { report -> EmployeeCard(node = report, level = 1) // Рекурсивно для вложенных уровней через expandable state } } } Поиск сотрудников
Полнотекстовый поиск по AD через LDAP-фильтр:
const filter = `(&(objectClass=person)(|(displayName=*${query}*)(mail=*${query}*)(sAMAccountName=*${query}*)))`; Производительность: wildcard в начале фильтра (*${query}*) не использует индекс AD, поиск медленный при большой базе. Для приложений с тысячами сотрудников — синхронизируем AD в Elasticsearch или PostgreSQL full-text search, поиск делаем там.
Синхронизация и кэш
AD — источник правды для данных о сотрудниках. Мобильное приложение работает с кэшем backend. Для актуальности: webhook-события через AD Event Log (если AD 2016+) или polling раз в 15-30 минут на изменения через uSNChanged атрибут.
При увольнении сотрудника аккаунт в AD деактивируется. Backend при следующем refresh_token видит failed LDAP lookup и инвалидирует JWT. Мобильный перенаправляется на логин.
Особенности Azure AD (Entra ID)
Если компания использует Azure AD (Microsoft Entra ID) — прямого LDAP нет, только Microsoft Graph API или OIDC. Graph API значительно удобнее: REST, JSON, богатая документация. GET /users/{id}?$select=displayName,mail,department,manager,memberOf возвращает всё то же, что и LDAP, но без ADO-библиотек.
Для гибридной среды (on-premise AD + Azure AD с Azure AD Connect) — данные синхронизируются, можно использовать либо Graph API, либо on-premise LDAP в зависимости от требований безопасности.
Что входит в работу
- Аудит текущей инфраструктуры AD/LDAP и мобильного приложения
- Проектирование архитектуры backend-прокси
- Реализация аутентификации через LDAP-bind с JWT
- Создание API для получения атрибутов, оргструктуры, поиска
- Настройка кэширования и синхронизации
- Интеграция с Azure Graph API (при необходимости)
- Документация и обучение команды заказчика
- Техническая поддержка на этапе эксплуатации
Ориентировочные сроки и стоимость
Интеграция AD/LDAP (backend-прокси + мобильный клиент + оргструктура + поиск): 3–6 недель. Стоимость типового проекта — от 150 000 до 400 000 рублей в зависимости от сложности и используемых технологий. Для точной оценки свяжитесь с нами для аудита.
Наша команда выполнила более 15 проектов по интеграции AD/LDAP для банков, ритейла и промышленности. Гарантируем совместимость с любыми LDAP-серверами (OpenLDAP, FreeIPA, Active Directory). Свяжитесь с нами для аудита и получите индивидуальное коммерческое предложение.







