Что проверено
Проверено на канале Email, без изменений на стороне Veriqa.
GitLab
Барьер. Из коробки вход не проходит:omniauth_openid_connect кладёт scope в запрос
grant_type=authorization_code, где RFC 6749 §4.1.3
его не предусматривает. Veriqa отвечает invalid_request, GitLab показывает:
args провайдера один флаг:
sub Veriqa, адрес из claim
email GitLab считает подтверждённым и своего письма-верификации не шлёт.
Если claim
email не приходит, GitLab не отказывает: он заводит пользователя, выдаёт сессию и
подставляет собственный служебный адрес вида temp-email-for-oauth-{login}@gitlab.localhost,
показывая подсказку заполнить профиль.Keycloak
Здесь Veriqa подключается к другому identity-provider как внешний OIDC-провайдер: Keycloak принимает вход у Veriqa и дальше сам выступает провайдером для своих приложений. Конфигурации почти нет. Keycloak импортирует discovery-документ Veriqa и заполняет все адреса сам, включаяjwks_uri, и сам же включает проверку подписи.
Барьер — не email, а фамилия. Схема профиля realm’а по умолчанию требует email, firstName
и lastName. Claim family_name Veriqa отдаёт только тогда, когда канал дал фамилию: Telegram и
MAX берут её из профиля мессенджера, где она необязательна, а Email не даёт её никогда. Поэтому
первый вход упирается в форму «Update Account Information» — всегда на канале Email и выборочно
на остальных.
Что сделать. Realm settings → User profile: снять признак обязательности с firstName и
lastName.
Две формы добора подряд. Если входу не хватает claim, который Veriqa добирает сама, Veriqa
спрашивает его у пользователя на своей форме, прежде чем вернуть вход. RP со своей формой добора
профиля — Keycloak, а также Logto — показывает сразу после неё вторую. Для такого приложения
выключите форму Veriqa членом ClaimCompletionFormEnabled: false в его записи
Veriqa:OpenIddict:Clients (см. Clients). При выключенной
форме недостающие claims не выдаются и вход не блокируют: RP спрашивает их на своей форме. Телефона
и email это не касается — Veriqa получает их своими путями.
Grafana
Барьер. Без claimemail Grafana не отказывает сразу — она ищет адрес по соглашению,
совместимому с GitHub: запрашивает {api_url}/emails, которого в OpenID Connect нет. Получает 404
и прекращает аутентификацию:
email. Канал Email даёт его сам; на канале, который адреса не
даёт (Telegram), адрес добирает Veriqa внутри входа, если email требуется, либо подставляет ваш
код — см. Обогащение claim’ов.
Учётная запись. Создаётся автоматически, email, name и login заполняются адресом.
Grafana не шлёт
nonce и не проверяет подпись id_token по JWKS — claims она разбирает из тела
токена. Ещё она пытается прочитать access token Veriqa как JWT и пишет в отладочный лог
token is not in JWT format: access token — не JWT (сейчас это непрозрачный reference-токен, во
время прогона был JWE), на вход это не влияет.Nextcloud
Барьеры здесь не в claims, а в транспорте, и оба снимаются настройкой Nextcloud. Только HTTPS. По HTTPuser_oidc отдаёт 404 со страницей «You must access Nextcloud with HTTPS
to use OpenID Connect». Проверка пропускает поток при HTTPS, в debug-режиме или при
app-настройке allow_insecure_http — последняя годится для внутреннего контура.
Защита от приватных адресов. Пока не выставлен allow_local_remote_servers=true, Nextcloud не
ходит на issuer в приватной сети. Диагностируется плохо: возврат отдаёт 403, а единственный след —
строка в nextcloud.log:
Если вы планируете сопоставлять учётные записи Nextcloud со своими по
sub, снимите uniqueUid
до первого входа: смена настройки не переименовывает уже заведённых пользователей.
Nextcloud проверяет подпись
id_token по JWKS и не обращается к /connect/userinfo вовсе:
все claims он берёт из id_token. Claims, которые Veriqa отдаёт только в userinfo, до него не
доедут — если они вам нужны, включите enrichLoginIdTokenWithUserinfo.Discourse
Плагинopenid_connect встроен в ядро — устанавливать нечего. Барьера два, и оба снимаются
настройками форума.
По умолчанию Discourse не запрашивает email. Настройка openid_connect_authorize_scope
содержит только openid. Для форума это тупик: без адреса учётная запись не создаётся, а вход
останавливается на форме регистрации. Задайте openid email profile.
Защита от приватных адресов. Пока issuer в приватной сети, Discourse к нему не пойдёт:
allowed_internal_hosts должен содержать его хост. В браузер при этом уезжает безликое
openid_connect_discovery_error — причину видно только при включённом
openid_connect_verbose_logging. В продакшне барьер не возникает.
Что проверено и что нет. Вход существующего пользователя проходит, связка пишется по sub
Veriqa, подпись id_token Discourse проверяет по JWKS. Автосоздание учётной записи не
проверено: у Discourse оно выполняется отдельным запросом из браузера и защищено анти-бот-
механикой.
Odoo
Модуль из поставки не подойдёт. Штатныйauth_oauth умеет только implicit flow: он просит
response_type=token, не шлёт nonce и не проверяет подпись. Veriqa отвечает
unsupported_response_type: implicit убран из
OAuth 2.1 как небезопасный. Снаружи это выглядит как страница ошибки вместо возврата на сайт.
Что ставить. Модуль auth_oidc из репозитория OCA
(ветка вашей версии Odoo). В настройке провайдера выберите
flow = OpenID Connect (authorization code flow) и заполните появившиеся поля: Token URL, JWKS
URL и Client Secret. Именно JWKS URL даёт Odoo проверять подпись Veriqa — и он её проверяет.
Учётная запись. Создаётся автоматически — свободная регистрация включена в чистой базе Odoo
по умолчанию, ничего дополнительно включать не нужно. Связка пишется по sub Veriqa в поле
oauth_uid, логином становится адрес. Если адрес не приходит, Odoo подставляет собственный
синтетический логин и всё равно заводит пользователя.
Moodle
Своего OIDC-клиента у Moodle нет; используется плагинauth_oidc, который Microsoft поставляет для Entra ID.
Вход проходит, пользователь создаётся, связка пишется по sub Veriqa — но три барьера придётся
снять, и два из них вы встретите даже в продакшне.
Плагин шлёт чужой параметр. В любом режиме, кроме «Microsoft Identity Platform», он
добавляет к запросу параметр resource, а когда поле в настройке пустое — подставляет зашитый
адрес Microsoft Graph. Veriqa отвечает invalid_target: Veriqa не регистрирует ресурсы
RFC 8707, поэтому не проходит никакое значение.
Выходов два, и тот, что на стороне Veriqa, ничего не требует от Moodle: включите для этого
client_id квирк уровня клиента drop-resource-parameter —
параметр снимается до валидации. Потребителя у него здесь нет, поэтому выданный токен совпадает
с тем, что получил бы клиент, никогда его не присылавший: ресурс не регистрируется, audience не
выдаётся.
Защита от приватных адресов — и от портов. Moodle блокирует исходящие запросы не только по
адресу (curlsecurityblockedhosts), но и по порту: curlsecurityallowedport по умолчанию
разрешает лишь 443 и 80. В отличие от остальных систем, этот барьер не исчезает сам в
продакшне — если ваш issuer слушает нестандартный порт, порт нужно разрешить явно. Диагностика
скупая: в браузере «Error in OpenID Connect. Please check logs», настоящая причина
(The URL is blocked.) видна только после включения отладочного режима плагина.
Двоеточие в идентификаторе. Если Moodle нечего взять для имени пользователя, кроме sub
Veriqa, вход упрётся в «The given username contains invalid characters»: sub имеет вид
telegram:1234 или email:адрес, а двоеточие Moodle в логинах не принимает. Два выхода:
запрашивать scope profile (тогда имя берётся из preferred_username) или включить
extendedusernamechars.
После создания. Moodle уводит нового пользователя на «дозаполните профиль»: имя и фамилия у
него обязательны, а канал их не всегда даёт.
Требование email: четыре разных поведения
Telegram адреса не даёт, и системы относятся к его отсутствию по-разному. Разница практическая: она определяет, нужен ли вам вообще подставленный адрес.
Как выглядит та же картина на CMS — в обзоре интеграций с CMS.
Локальная проверка: у каждой системы свой выключатель
Если вы поднимаете связку на своей машине, issuer оказывается в приватной сети, и почти каждая система защищается от обращений туда собственным флагом:
Четыре первых барьера исчезают в продакшне вместе с публичным issuer. Moodle — исключение:
он ограничивает ещё и порт, поэтому остаётся препятствием и на публичном адресе, если issuer
слушает не 443 и не 80. Подробнее о локальных стендах —
Локальная проверка.
Не проверено
- Каналы, кроме Email. На Telegram ожидаемое отличие — требование адреса (см. таблицу выше).
- Слияние с уже заведённой локальной учётной записью — кроме Discourse, все системы выше проверены на вновь создаваемом пользователе.
- Роли, группы и права. Пользователь получает роль по умолчанию; маппинг групп из claim’ов не проверялся ни в одной системе.
- Повторный вход и обновление данных профиля из провайдера при следующем входе.