# Active Directory и SSO — Решение проблем

Документ описывает типовые проблемы Active Directory и SSO. Внутри собраны разделы по синхронизации с AD, фильтрам, расширенным настройкам AD, SSO, LDAP/LDAPS и управлению пользователями из AD. Для каждой проблемы указаны симптом, что проверить, решение и эскалация в поддержку 1Ф.

**Как пользоваться этим документом**

Секции организованы по типам проблем. Для каждой:

1. **Симптом** — что описывает клиент
2. **Что проверить** — шаги диагностики
3. **Решение** — что сделать
4. **Эскалация** — когда обращаться в поддержку 1Ф

---

## 1. Синхронизация с AD — ошибки и сбои

Самая частая группа проблем по теме AD.

**1.1 Автоматическая синхронизация с AD не работает**

**Симптом:** «автоматическая синхронизация с AD не происходит», «ADSyncJob не работает».

**Что проверить:**

- Настройки синхронизации — заполнены ли (Администрирование → Синхронизация)
- Расписание — настроен ли интервал
- Доступность AD-сервера — сетевая связность
- Логи — текст ошибки ADSyncJob
- Платформа — на PG ADSyncJob может не работать (известная проблема)

**Эскалация:** если настройки корректны, AD доступен, но синхронизация не идёт — обратиться в поддержку 1Ф.

**1.2 Ошибки при настройке синхронизации AD**

**Симптом:** «при настройке синхронизации AD возникают ошибки».

**Что проверить:**

- Строка подключения — формат LDAP://domain:port
- Учётная запись для подключения — достаточно ли прав
- SSL/TLS — правильный ли порт (389 для LDAP, 636 для LDAPS)
- Сертификат — доверенный ли (для LDAPS)

**1.3 Учётные записи создаются без реквизитов (только SID)**

**Симптом:** «при синхронизации с AD создаётся пользователь, но без реквизитов — только SID из AD».

**Что проверить:**

- Маппинг атрибутов — заполнен ли (ФИО, email, должность и т.д.)
- Расширенные настройки — настроен ли маппинг нужных AD-атрибутов на поля 1Ф
- Логи — нет ли ошибок при чтении атрибутов

**Эскалация:** если маппинг настроен, но данные не заполняются — обратиться в поддержку 1Ф.

**1.4 При выгрузке пользователя из AD — ошибка**

- Версию системы: на сборке с политикой ожидания по операции выгрузка пользователей AD и проверка SID предела 25 секунд не имеют и на медленном каталоге не отказывают. Если отказ приходит и на такой сборке — пришлите версию в поддержку.
- Полноту выдачи при выгрузке леса: неполная выдача помечается признаком неполноты, полный список в этом случае не выдаётся.
- Исходную причину в журнале: отказ в доступе и другие сбои каталога приходят своей причиной, а не превышением ожидания.

**Симптом:** «при выгрузке (импорте) пользователя из AD — ошибка».

**Что проверить:**

- Текст ошибки
- Конкретный пользователь или все — если один, возможна проблема в его AD-атрибутах
- Версия системы

**1.5 ObjectDisposedException: 'DirectoryEntry' (Windows, сборки 2.268)**

**Симптом:** При плановой синхронизации с AD (`ADSyncJob`) в лог массово сыпятся ошибки:
```
SyncUsers for [ФИО]. Noninteruptable error: System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'DirectoryEntry'.
```
Джоб падает с `Error syncing users from AD`.

**Платформа:** Windows/IIS. Linux-инсталляции (Novell-провайдер) не затронуты.

**Причина:** Обращение к `DirectoryEntry` уже после его освобождения при чтении отдельных AD-атрибутов во время синхронизации — зависело от конкретного маппинга профиля.

**Что проверить:**

- Хост — Windows?
- Текст ошибки в логе — содержит `ObjectDisposedException` и `DirectoryEntry`?
- Версия системы — сборка 2.268?

**Решение:** Устранено на уровне платформы, маппинг профиля менять не нужно. Если ошибка воспроизводится на актуальной сборке — обратиться в поддержку 1Ф.

**1.6 Дерево подразделений не раскрывается — 504 Gateway Time-out**

**Симптом:** в настройках синхронизации с AD не раскрывается дерево подразделений: узел не открывается, в браузере вместо содержимого появляется `504 Gateway Time-out`. Повторяется через одну и ту же паузу — обычно 60 секунд. В журнале площадки за эти минуты может не быть ни одной записи.

**Что проверить:**

- Версию системы: на сборке с пределом ожидания операций с каталогом вместо `504` приходит своя ошибка с текстом «Превышен предел ожидания операции с каталогом» и указанием хоста, базы поиска, области и длительности, а в журнал — запись уровня предупреждение. Если `504` приходит и на такой сборке — пришлите версию в поддержку.
- Журнал площадки: поиск по тексту «Превышен предел ожидания операции с каталогом». Запись содержит хост, базу поиска, область и имя операции — этого достаточно, чтобы понять, какой запрос завис.
- Настройки предела ожидания — `LDAP_OperationTimeoutSeconds`, при его отсутствии `DirectoryServices_OperationTimeoutSeconds`; без настроек действует значение 25 секунд. Если каталог стабильно отвечает дольше, предел стоит поднять до 30–40 секунд.
- Доступность каталога с сервера приложения: домен резолвится, порт 389 доступен, учётная запись сервиса верна. Ключ глобального каталога на эту проблему не влияет — он влияет только на выбор контроллеров домена.

**Решение:** при своей ошибке превышения ожидания увеличьте предел настройкой площадки (см. «8.1» в справочнике по синхронизации с AD). Если предел не помогает, каталог отвечает дольше, чем допускает лимит прокси: уменьшайте объём выборки фильтрами профиля синхронизации (`UsersADFilter`, `GroupsADFilter`, список организационных единиц) либо переносите площадку на Linux-сборку, где тот же предел применяется иначе.

**Эскалация:** если после поднятия предела раскрытие не возвращается — в поддержку 1Ф с версией сборки, найденной записью журнала (хост, база, область, операция), значением предела ожидания и выводом проверки доступности каталога с сервера приложения.

---

## 2. Фильтры синхронизации AD

Частая проблема при настройке фильтров AD.

**2.1 Фильтр пользователей/ОЕ не работает**

**Симптом:** «не работает фильтр орг. единиц синхронизации», «не создаются пользователи при наличии фильтра».

**Что проверить:**

- Синтаксис LDAP-фильтра — корректен ли
- Результат фильтра — возвращает ли AD объекты при таком фильтре (проверить через ldapsearch / AD Explorer)
- Формат — экранированы ли спецсимволы

**2.2 Фильтр AD > 100 символов — ошибка**

**Симптом:** «при создании фильтра на >100 символов в "AD фильтр пользователей" или "AD фильтр групп" — ошибка».

**Решение:** известное ограничение — поле в БД ограничено по длине.

**Эскалация:** если нужен длинный фильтр — обратиться в поддержку 1Ф для увеличения поля.

---

## 3. Расширенные настройки AD

Повторяющаяся проблема.

**3.1 Не добавляется новый AD-ключ в расширенные настройки**

**Симптом:** «не работает добавление нового AD-ключа в расширенные настройки пользователя при настройке синка с AD».

**Что проверить:**

- Версия системы — баг воспроизводится в нескольких версиях
- Интерфейс — AdminSPA или старая админка

**Эскалация:** известный повторяющийся баг — обратиться в поддержку 1Ф с указанием версии.

**3.2 Нет возможности забрать EmployeeID / EmployeeNumber из AD**

**Симптом:** «нужно получить табельный номер из AD, но атрибуты EmployeeID / EmployeeNumber недоступны».

**Решение:** стандартный маппинг не включает эти атрибуты. Нужно добавить через расширенные настройки AD-синхронизации (если работает, см. 3.1) или через пользовательскый маппинг.

---

## 4–6. SSO, LDAP/LDAPS и пользователи из AD

**4.1 Настройка SSO для Web и Desktop**

**Симптом:** «как настроить SSO для веб-версии и десктоп-клиента?»

**Решение:** SSO настраивается через провайдер авторизации (OAuth, SAML, Kerberos). Для веба — стандартный redirect. Для десктоп-клиента — в зависимости от протокола (Kerberos через спецнастройку, SAML через встроенный браузер). Администрирование → Провайдеры авторизации.

**4.2 2FA + SSO в доменной среде**

**Симптом:** «хотим 2FA для внешнего доступа, но SSO по Kerberos для сотрудников в домене».

**Решение:** возможны комбинированные сценарии — Kerberos для внутренней сети, 2FA для внешней. Настройка через провайдеры + условия.

**4.3 Некорректное отображение провайдера AD в AdminSPA**

**Симптом:** «провайдер Active Directory отображается некорректно в AdminSPA».

**Что проверить:**

- Версия системы
- Наличие нескольких провайдеров

### 4.4 Kerberos на Linux (Kestrel/Docker) — диагностика

**Контекст:** с v2.268.302 1Форма поддерживает нативную аутентификацию Kerberos без IIS — через ASP.NET Core Negotiate в Kestrel. Применяется при разворачивании в Docker/Linux в доменной среде. Полная настройка — [admin.md § Kerberos на Linux](https://help.1forma.ru/domains/auth/admin.md).

```mermaid
sequenceDiagram
    participant U as Клиент
    participant F as Сервер 1Ф
    participant K as KDC
    U->>F: запрос ресурса
    F-->>U: 401, схема Negotiate (если winAuthHost = Kestrel)
    U->>K: запросить билет по SPN HTTP/hostname@REALM
    alt SPN, DNS и keytab корректны
        K-->>U: Kerberos-билет
        U->>F: токен Negotiate (Kerberos)
        F->>F: проверка по keytab (KRB5_KTNAME)
        F-->>U: вход выполнен
    else SPN, DNS или keytab не настроены
        U->>F: понижение SPNEGO до NTLM
        F-->>U: при RequireKerberos = true вход отклонён (401)
    end
```

**Симптом 1: «SSO не работает на Linux-стенде, пользователь получает всплывающее окно ввода пароля или 401».**

Что проверить:

1. **Статус приложения** — `GET /api/admin/auth/kerberos/status` (требует прав администратора). Должно быть `winAuthHost = "Kestrel"` и `negotiateSchemeRegistered = true`. Если `winAuthHost = "None"` — Windows-auth выключена в `appsettings.json`, нужно проставить `Auth:WinAuthHost = "Kestrel"`.
2. **Инфраструктура контейнера** — установлена библиотека `libgssapi-krb5-2`, существует keytab с SPN вида `HTTP/<hostname>@REALM`, переменная `KRB5_KTNAME` указывает на keytab.
3. **DNS и SPN** — клиент резолвит сервер по FQDN, для которого создан SPN; PTR-запись соответствует прямой записи. Без этого Windows-клиент молча понижает SPNEGO до NTLM.
4. **Браузер клиента** — адрес сервера в Local Intranet / Trusted Sites (для IE/Edge), Negotiate включён.

#### Симптом 2: RequireKerberos отклоняет NTLM authentication rejected

Что произошло: вход отклонён, потому что фактический протокол — NTLM, а не Kerberos. Это ожидаемое поведение настройки `RequireKerberos`.

Что проверить через SQL — какой протокол реально использовался при последних попытках:

```sql
select top 20
    l.LoginDate, u.Nick, l.AuthProtocol, l.UserComputerName, l.IP
from LoginsLog l
left join Users u on u.UserID = l.UserID
where l.LoginDate > dateadd(hour, -1, getdate())
order by l.LoginDate desc;
```

Если в `AuthProtocol` массово `NTLM` — согласование Kerberos не проходит ни у одного клиента, причина в инфраструктуре (см. пункты 2–4 выше), а не в одном пользователе. До устранения — `Auth:RequireKerberos: false`, чтобы NTLM-вход работал.

**Симптом 3: «Endpoint статуса возвращает `negotiateSchemeRegistered = false`, хотя `winAuthHost = "Kestrel"`».**

Приложение стартовало без Windows-аутентификации. Причина обычно в `appsettings.{Environment}.json` или в переопределении через переменную окружения, которое перекрывает `Auth:WinAuthHost`. Перезапустить приложение после исправления, повторить проверку статуса.

**Эскалация:** при инфраструктурных проблемах (keytab, SPN, KDC) — на администратора Linux/AD. Платформа сама согласование Kerberos не выполняет, только использует результат ASP.NET Core Negotiate.

**4.5 Windows-вход (Negotiate): «Пользователь не найден» / User = -1**

**Симптом:** при входе через Windows (Negotiate) часть запросов (обычно фоновые/повторные) падает с «Пользователь не найден» (HTTP 400), в логах — `User = -1`.

**Что проверить:** версию системы — устранено в 2.268.483. На более ранних версиях при Negotiate-входе пользователь мог не проставляться в контекст запроса, и запрос доходил до бизнес-логики с неопознанным пользователем.

**Решение:** обновить систему до 2.268.483 или выше. На актуальных версиях запрос с неопознанным пользователем на защищённом (`[Authorize]`) эндпоинте возвращает 401, а не доходит до бизнес-логики.

**4.6 SSO-вход отклонён: «Ambiguous attribute value»**

**Симптом:** вход через внешний провайдер не проходит, в журнале приложения — ошибка `Ambiguous attribute value: <значение>`.

**Что проверить:** в `dbo.UserExternalAccounts` для этого сервиса есть несколько строк, которые СУБД считает одинаковыми по `ExternalUid` — различающиеся только регистром на MS SQL или только хвостовыми пробелами. Среди них нет ровно одной, совпадающей с пришедшим значением посимвольно, поэтому выбрать привязку нельзя.

**Решение:** оставить одну строку — соответствующую действующему пользователю, остальные удалить. Настройки провайдера при этом менять не нужно.

**Когда обращаться в поддержку:** если таких пар много и определить нужную строку по данным сервиса не получается — с указанием сервиса и числа затронутых пользователей.

---

**5. LDAP / LDAPS**

**5.1 Переход с LDAP на LDAPS**

**Симптом:** «нужно перейти с LDAP (389) на LDAPS (636)».

**Решение:**

1. Убедиться, что сертификат LDAP-сервера доверенный (или добавить в trust store)
2. Изменить строку подключения: порт 389 → 636, протокол LDAP → LDAPS
3. Проверить синхронизацию после изменения

**Эскалация:** если после смены порта/протокола синхронизация не работает — проблема с сертификатом.

**5.2 Соединение с LDAP/AD обрывается на проверке сертификата**

**Симптом:** вход через AD, поиск в каталоге или синхронизация каталога прекращается на этапе TLS, до проверки логина и пароля.

**Что проверить:**

1. Задан ли список доверенных отпечатков — `Auth:Ldap:TrustedCertificateThumbprints` в `appsettings.json` или `LdapTrustedCertificateThumbprints` в `appSettings` устаревшего `web.config`
2. Журнал приложения на ошибку сверки отпечатка: в ней указаны обозначение пути (`AD.Authentication`, `AD.StatusSearch`, `DirectoryInterop.Sync`) и SHA-256 сертификата, предъявленного сервером
3. Совпадает ли этот отпечаток с одной из записей списка — после удаления двоеточий и пробелов запись должна содержать ровно 64 шестнадцатеричных символа

**Решение:** дополнить список актуальным отпечатком. При смене сертификата добавляйте новый заранее, не удаляя прежний. Некорректная запись отклоняет соединение так же, как несовпадение: пустым список от этого не становится.

**Эскалация:** в поддержку 1Ф с обозначением пути, SHA-256 из журнала и составом списка отпечатков. Настройка ключей описана в [администрировании аутентификации](https://help.1forma.ru/domains/auth/admin.md).

**5.3 Вход по балансируемому имени домена падает после включения проверки сертификата**

**Симптом:** подключение идёт по имени домена (`ldaps://company.local:636`), отвечающий контроллер предъявляет сертификат на своё имя, и вход отклоняется при включённой проверке сертификата.

**Причина:** штатная проверка требует совпадения имени узла в сертификате с адресом подключения, а при балансировке между контроллерами домена оно не совпадает по определению.

**Решение:** выключите проверку (`LdapValidateServerCertificate = false`) и задайте в `Auth:Ldap:TrustedCertificateThumbprints` SHA-256 отпечаток издающего центра сертификации, а не конкретного контроллера — один отпечаток покрывает все контроллеры и их автоматический перевыпуск. Снять отпечаток: `openssl x509 -in ca.crt -noout -fingerprint -sha256`. Проверить, что записан отпечаток именно центра: войдите несколько раз подряд — балансировщик отдаёт разные контроллеры, поэтому стабильный вход подтверждает отпечаток центра, а периодические отказы означают, что записан отпечаток одного контроллера. С пустым списком оставлять проверку выключенной нельзя: подлинность сервера тогда не проверяется вовсе.

**Эскалация:** если отпечаток центра задан, а отказы остаются — в поддержку 1Ф с обозначением пути из журнала, SHA-256 предъявленного сертификата и списком отпечатков.



---

**6. Пользователи из AD — управление**

**6.1 Нельзя редактировать пользователей, импортированных из AD**

**Симптом:** «не удаётся редактировать информацию о пользователе, синхронизированном из AD».

**Решение:** ожидаемое поведение — поля, маппированные из AD, блокируются для ручного редактирования. Изменения нужно делать в AD и пересинхронизировать. Для полей, не маппированных из AD, редактирование доступно.

**6.2 Где в AdminSPA видны юниты из AD**

**Симптом:** «где в новой админке видны орг. единицы, засинкованные из AD?»

**Решение:** Администрирование → Синхронизация → вкладка «Организационные единицы». В AdminSPA — раздел Пользователи → фильтр по источнику.

**6.3 Смена пароля при доменной авторизации**

**Симптом:** «как сменить пароль пользователя, если настроена доменная авторизация?»

**Решение:** при доменной авторизации пароль меняется в Active Directory, не в 1Ф. В 1Ф пароль для таких пользователей не хранится.

**6.4 IdP аутентифицировал пользователя, но 1Форма отклонила вход (SAML)**

**Симптом:** «на стороне провайдера вход проходит, а в 1Форму не пускает»; в журнале приложения — предупреждение о том, что SAML-ответ отклонён.

**Что проверить:**

- Инициируется ли вход со стороны IdP (портал провайдера, ссылка на приложение) — такие ответы принимаются только при включённом `AllowUnsolicitedResponse` у провайдера.
- Не прошло ли между началом входа и ответом больше 10 минут — запись о запросе к этому времени истекает.
- Не открыт ли вход в нескольких вкладках и не используется ли повторно старый ответ: ответ принимается один раз.
- Настройки `CertificateValidationMode` и `RevocationMode` у провайдера, если отклонение происходит на проверке подписи.

**Когда обращаться в поддержку:** если вход начинается из 1Формы, укладывается в 10 минут и выполняется однократно, а ответ всё равно отклоняется — с указанием провайдера и времени попытки.

---

## Чеклист для первичной диагностики AD/SSO и обращения в поддержку 1Ф

При любом обращении по AD/SSO соберите базовую информацию:

1. **Тип проблемы** — синхронизация, фильтры, расширенные настройки, SSO, LDAP, управление пользователями
2. **Тип подключения** — AD (LDAP), AD (LDAPS), SAML, OAuth, Kerberos
3. **Платформа БД** — MS SQL или PostgreSQL (PG имеет ограничения ADSyncJob)
4. **Версия системы**
5. **Интерфейс** — AdminSPA или старая админка
6. **Текст ошибки из лога**
7. **Количество пользователей / ОЕ в AD** — влияет на производительность синка
8. **Предел ожидания операций с каталогом** — `LDAP_OperationTimeoutSeconds` / `DirectoryServices_OperationTimeoutSeconds`; при отсутствии настроек действует значение из кода (25 секунд)
9. **Запись о превышении ожидания в журнале** — текст «Превышен предел ожидания операции с каталогом»; из неё берутся хост, база поиска, область и операция

**Когда обращаться в поддержку 1Ф**

Передайте обращение в поддержку 1Ф, если столкнулись с одним из следующих случаев:

- ADSyncJob не работает на PG (известная проблема)
- Не добавляется AD-ключ в расширенные настройки (повторяющийся баг)
- Фильтр >100 символов не сохраняется (ограничение поля)
- Пользователи создаются без реквизитов при корректном маппинге (баг)
- Проблемы с сертификатами LDAPS
- Настройка комбинированного SSO + 2FA
