Аутентификация и единый вход
Сотрудники входят в консоль и Studio одним из трёх способов. Способы описываются в главном конфиге как стратегии (authStrategies), их может быть несколько одновременно: например, логин и пароль платформы для подрядчиков и единый вход через Keycloak для сотрудников компании.
| Стратегия | type | Когда подходит |
|---|---|---|
| Базовая: логин и пароль платформы | basic | Небольшие команды, тестовые стенды, подрядчики без учётной записи в корпоративном каталоге. Поддерживает сброс пароля по почте и второй фактор |
| Единый вход OpenID Connect | oauth2 | Корпоративный провайдер: Keycloak, ADFS, Okta, Яндекс ID для организаций и другие совместимые с OpenID Connect |
| Служба каталогов | ldap | Active Directory, OpenLDAP, FreeIPA: вход по учётной записи домена с проверкой пароля в каталоге |
SAML не поддерживается: для провайдеров, которые умеют и SAML, и OpenID Connect, используйте OpenID Connect.
Метод входа у платформы один, он задаётся при установке: первая стратегия в списке collaboratorsAuthStrategies. Только она доступна на странице входа (выбор способа при входе не предлагается), маршруты входа остальных стратегий из этого списка закрыты и отвечают 403. Чтобы перейти на единый вход, опишите стратегию в authStrategies и поставьте её идентификатор первым (единственным) в collaboratorsAuthStrategies; базовая стратегия default при этом может остаться в authStrategies, но входить через неё станет нельзя. Учётные записи, созданные другими стратегиями, сохраняют членство в рабочих пространствах.
{
"collaboratorsAuthStrategies": ["keycloak"],
"authStrategies": {
"default": { "type": "basic", "allowSelfSignup": false, "options": { "twoFactor": "optional" } },
"keycloak": { "type": "oauth2", "label": "Keycloak", "allowSelfSignup": true, "options": { "...": "см. ниже" } }
}
}
Базовая стратегия
Параметры в authStrategies.<id>.options:
| Параметр | По умолчанию | Назначение |
|---|---|---|
maxLoginAttempt | 5 | Число неудачных попыток входа до блокировки учётной записи; -1 отключает блокировку |
lockoutDuration | 15m | Длительность блокировки |
passwordMinLength | не задан | Минимальная длина пароля |
requireComplexPassword | false | Пароль должен содержать символы трёх из четырёх групп (строчные, прописные, цифры, спецсимволы) и не быть словарным |
passwordExpiryDelay | не задан | Срок действия пароля, например 90d; после истечения пользователь задаёт новый при входе |
twoFactor | off | Второй фактор: off, optional (пользователь подключает сам в меню профиля), required (каждый подключает при следующем входе) |
Дополнительно на каждый IP-адрес действует лимит 30 неудачных входов за 15 минут.
Сброс пароля по почте
Ссылка «Забыли пароль?» появляется на странице входа, когда настроена исходящая почта платформы: раздел mail главного конфига или вкладка «Почта» на странице «Настройки сервера» консоли. Пользователь указывает адрес, получает письмо со ссылкой (действует час) и задаёт новый пароль; при этом все его открытые сеансы завершаются, а блокировка снимается. Ответ сервера не раскрывает, существует ли учётная запись; на один адрес отправителя действует лимит пять запросов в час. Интеграционным учётным записям письма не отправляются: их секрет перевыпускает администратор.
"mail": {
"transport": "smtp://iqbot:secret@mail.example.com:587",
"from": "iQBot <iqbot@example.com>"
}
transport принимает строку SMTP (smtps:// для TLS) или объект с параметрами nodemailer (host, port, secure, auth).
Второй фактор
Второй фактор это одноразовые коды приложения-аутентификатора (Яндекс Ключ, Google Authenticator, FreeOTP и любое другое приложение TOTP). При подключении пользователь сканирует QR-код, подтверждает код и получает восемь кодов восстановления на случай потери телефона; каждый код работает один раз.
optional: пункт «Двухфакторная аутентификация» в меню профиля, пользователь подключает и отключает сам (отключение требует пароль и текущий код).required: после ввода верного пароля страница входа предлагает подключить приложение; без этого войти нельзя, отключить из профиля тоже.- Если телефон потерян, администратор в разделе «Пользователи» выбирает «Сбросить второй фактор»; при
requiredпользователь подключит приложение заново при следующем входе. - Секрет хранится в базе зашифрованным ключом приложения (
appSecretглавного конфига). Смена ключа делает вторые факторы нечитаемыми: пользователям придётся подключить их заново.
Второй фактор относится только к базовой стратегии; при едином входе его обеспечивает провайдер.
OpenID Connect (Keycloak и другие)
Что настроить у провайдера
- Создайте клиента (в Keycloak: Clients → Create client) типа OpenID Connect, конфиденциального (Client authentication включён), с разрешённым потоком Standard flow (authorization code).
- Укажите адрес возврата (Valid redirect URIs):
https://<адрес iQBot>/api/v2/admin/auth/login-callback/oauth2/<id стратегии>. Для выхода (Valid post logout redirect URIs):https://<адрес iQBot>/admin/login. - Запишите идентификатор клиента и секрет.
- Убедитесь, что в токене или в userinfo есть адрес электронной почты (область
email, у пользователей заполнено поле e-mail). Платформа находит учётную запись по e-mail.
Что настроить в iQBot
"authStrategies": {
"keycloak": {
"type": "oauth2",
"label": "Keycloak",
"allowSelfSignup": true,
"hidden": false,
"options": {
"issuer": "https://sso.example.com/realms/iqbot",
"clientID": "iqbot-admin",
"clientSecret": "<секрет клиента>",
"scope": "openid profile email",
"callbackURL": "https://bot.example.com/api/v2/admin/auth/login-callback/oauth2/keycloak"
},
"fieldMapping": { "email": "email", "firstname": "given_name", "lastname": "family_name" }
}
}
| Параметр | Назначение |
|---|---|
issuer | Адрес издателя. Конечные точки читаются из <issuer>/.well-known/openid-configuration |
authorizationURL, tokenURL, userInfoURL, jwksURL, endSessionURL | Явные адреса конечных точек. Нужны, если нет discovery или сервер iQBot обращается к провайдеру по другому имени, чем браузер пользователя (например, внутри контейнерной сети): тогда authorizationURL и endSessionURL указывают имя для браузера, а tokenURL, userInfoURL и jwksURL внутреннее имя |
clientID, clientSecret | Данные клиента у провайдера |
scope | Запрашиваемые области, по умолчанию openid profile email |
callbackURL | Адрес возврата, зарегистрированный у провайдера. Если не задан, берётся <IQB_EXTERNAL_URL>/api/v2/admin/auth/login-callback/oauth2/<id> |
fieldMapping | Соответствие полей платформы (email, firstname, lastname) полям профиля провайдера (claims или userinfo). По умолчанию стандартные claims OpenID Connect |
allowSelfSignup | Создавать учётную запись при первом входе. При false войти могут только пользователи, которых администратор заранее добавил в разделе «Пользователи» с этой стратегией |
Как проходит вход: кнопка «Войти с помощью Keycloak» ведёт на страницу провайдера, после входа провайдер возвращает браузер на callbackURL, платформа проверяет подпись идентификационного токена, читает профиль, находит или создаёт учётную запись и открывает консоль. Выход из консоли завершает сеанс и у провайдера (RP-initiated logout), если у него есть end_session_endpoint.
Новая учётная запись попадает в рабочие пространства, в authStrategies которых указана стратегия (файл workspaces.json), с ролью defaultRole этого пространства; если таких пространств нет, в пространство default. Чтобы управлять доступом централизованно, оставьте allowSelfSignup: false и добавляйте сотрудников в разделе «Пользователи», выбирая стратегию в поле «Стратегия аутентификации»: пароль таким записям не нужен.
Проверка на стенде
Keycloak для проверки поднимается одной командой: docker run -d --name keycloak -p 8080:8080 -e KC_BOOTSTRAP_ADMIN_USERNAME=admin -e KC_BOOTSTRAP_ADMIN_PASSWORD=admin quay.io/keycloak/keycloak:26.0 start-dev. Создайте realm, клиента и пользователя с адресом электронной почты, пропишите стратегию, перезапустите iQBot и войдите. Платформа пишет в журнал строку Authentication strategy "<id>": OpenID Connect / OAuth 2 при запуске и Strategy "<id>": sign-in failed с причиной при ошибке входа.
LDAP и Active Directory
"authStrategies": {
"corp": {
"type": "ldap",
"label": "Учётная запись домена",
"allowSelfSignup": true,
"options": {
"serverUrl": "ldaps://dc01.example.com:636",
"bindDn": "cn=iqbot-reader,ou=service,dc=example,dc=com",
"bindCredentials": "<пароль служебной записи>",
"searchBase": "ou=people,dc=example,dc=com",
"searchFilter": "(|(sAMAccountName={{username}})(mail={{username}}))",
"timeout": 5000,
"tlsEnabled": false,
"certificates": ["/etc/iqbot/ca.pem"]
},
"fieldMapping": { "email": "mail", "firstname": "givenName", "lastname": "sn" }
}
}
| Параметр | Назначение |
|---|---|
serverUrl | ldap:// или ldaps:// с портом |
bindDn, bindCredentials | Служебная учётная запись с правом чтения каталога. Ею платформа ищет запись пользователя |
searchBase, searchFilter | Где и как искать запись. {{username}} заменяется тем, что пользователь ввёл в поле «Email» (значение экранируется, инъекция в фильтр невозможна). Для Active Directory обычно (sAMAccountName={{username}}) или (userPrincipalName={{username}}), для OpenLDAP (uid={{username}}) |
timeout | Тайм-аут подключения и поиска, мс |
tlsEnabled | Для ldap:// включает StartTLS перед привязкой; для ldaps:// не нужен |
certificates | Пути к сертификатам доверенных центров, если у каталога собственный ЦС |
fieldMapping | Атрибуты каталога для полей платформы. Адрес электронной почты обязателен: по нему хранится учётная запись; если атрибута нет, используется введённое имя пользователя |
Вход: пользователь вводит имя учётной записи (или адрес) и пароль на обычной форме входа; платформа находит запись служебной учётной записью и проверяет пароль привязкой от имени найденной записи. Неверный пароль, неизвестный пользователь и неоднозначный результат поиска отвечают одинаково («Неверный логин или пароль»); недоступность каталога пишется в журнал как ошибка. Блокировка попыток та же, что у базовой стратегии.
Пароли пользователей каталога в платформе не хранятся, поэтому сброс пароля и второй фактор для них не действуют: этим управляет каталог.
Интеграционные учётные записи
Учётная запись для iQChannels создаётся в базовой стратегии с признаком «интеграция»: у неё длинный секрет вместо пароля, который администратор перевыпускает в разделе «Пользователи»; сброс пароля по почте, второй фактор и вход в консоль к ней не применяются. Подробнее в разделе Подключение к iQChannels.
Если вход не работает
| Симптом | Причина |
|---|---|
| Страница входа показывает форму пароля вместо единого входа (или наоборот) | Метод входа — первая стратегия в collaboratorsAuthStrategies; проверьте порядок списка и перезапустите сервер |
| Вход через стратегию отвечает 403 «This sign-in method is disabled on this platform» | Стратегия есть в collaboratorsAuthStrategies, но не первая: на платформе один метод входа |
| После входа у провайдера «Сеанс входа устарел или открыт в другом браузере» | Браузер не вернул cookie сеанса: между переходом к провайдеру и возвратом прошло больше 10 минут, либо адрес callbackURL отличается по домену или схеме от адреса, с которого начался вход |
| «Провайдер не вернул адрес электронной почты» | В токене нет claim email: добавьте область email в scope, проверьте заполненность e-mail у пользователя или задайте fieldMapping.email |
| «Учётная запись не найдена. Попросите администратора добавить вас» | allowSelfSignup: false, а запись не создана заранее |
| Вошёл, но «нет доступа ни к одному рабочему пространству» | Запись создана, но не состоит ни в одном пространстве: добавьте её в разделе «Пользователи» или укажите стратегию в authStrategies пространства |
LDAP: все входы отвечают «Неверный логин или пароль», в журнале the directory is not available | Неверный serverUrl, закрыт порт, неверная служебная запись или сертификат; детали в журнале |
| Невозможно подключиться к Keycloak из контейнера | Внутри контейнерной сети провайдер доступен по другому имени: задайте tokenURL, userInfoURL, jwksURL с внутренним именем, оставив issuer и authorizationURL внешними |