Двойная аутентификация: когда два охранника мешают друг другу

Двойная защита убивает саму себя: как я развязал узел конфликтующей аутентификации
Задача стояла простая на первый взгляд: запустить Management UI для проекта borisovai-admin. Казалось, что админ-панель встанет и будет работать. Но когда я подключил её к боевой инфраструктуре, выяснилось нечто интересное — UI запустилась, но пройти аутентификацию было невозможно.
Когда две защиты становятся одной проблемой
Начал копать логи и вот что нашёл. В инфраструктуре уже была слоёная защита: Traefik с плагином ForwardAuth отправлял все запросы на Authelia для двухфакторной аутентификации. Это первый уровень охраны — на уровне прокси. Здесь логика простая: если запрос идёт на admin.borisovai.tech, Traefik вежливо перенаправляет пользователя в Authelia.
Но когда я добавил Management UI с встроенной OIDC-аутентификацией через express-openid-connect, произошло вот что: пользователь уже прошёл Authelia на уровне Traefik, но Management UI не поверил ему и снова отправил на Authelia через OIDC. Два редиректа подряд — и браузер начинает петлять между разными провайдерами аутентификации. Типичная ситуация, когда каждый охранник требует личный документ, не доверяя соседу.
Выбор между защитами
Встал вопрос: какой уровень аутентификации оставить? Отключить Traefik ForwardAuth? Отключить OIDC в Management UI? Или искать способ их синхронизировать?
Я выбрал проверенный путь — оставить Traefik ForwardAuth как основную защиту, а OIDC отключить. Логика здесь такая: раз у нас уже есть надёжная защита на уровне прокси с поддержкой 2FA через Authelia, зачем добавлять второй слой? Внутри же Management UI я оставил legacy session — простую аутентификацию по логину и паролю. Получилось двухуровневое решение, но на разных слоях: внешняя защита через прокси и внутренняя через сессию.
После изменений Management UI перезапустился без OIDC-интеграции. Теперь схема работает так: вы входите в https://admin.borisovai.tech, Traefik перенаправляет вас в Authelia, вы проходите двухфакторную аутентификацию, а потом попадаете на страницу логина самой админ-панели, где вводите учётные данные Management UI.
Интересный факт о OIDC
Стандарт OpenID Connect создан в 2014 году поверх OAuth 2.0 именно для решения проблем единого входа. Но мало кто знает, что OIDC работает лучше всего, когда он — единственный поставщик идентификации в системе. Как только вы пытаетесь слоить несколько провайдеров, начинаются конфликты. Классическая ловушка — стараться защитить приложение со всех сторон и получить вместо этого лабиринт редиректов.
Неприятный бонус: проблема с .ru доменами
Во время работы я обнаружил, что A-записи для admin.borisovai.ru и auth.borisovai.ru не добавлены у регистратора IHC. Let’s Encrypt не может выдать сертификаты для доменов, которых нет в DNS. Решение пришло быстро — нужно добавить эти A-записи в панели регистратора, указывая на IP 144.91.108.139. Казалось бы, мелочь, но именно такие детали часто становятся причиной того, что production не поднимается.
Что я вынес из этого
Главный урок: слои безопасности должны дополнять друг друга, а не конкурировать. Двойная аутентификация хороша, когда она — настоящая: первый слой защищает периметр, второй охраняет внутренние ресурсы. Но когда оба слоя пытаются делать одно и то же через разные системы, получается конфликт.
Теперь Management UI работает, защита работает, и никто не просит удостоверения дважды. Инфраструктура проекта borisovai-admin стала на один уровень надёжнее.
😄 Почему Prometheus не пришёл на вечеринку? Его заблокировал firewall.
Метаданные
- Session ID:
- grouped_borisovai-admin_20260208_2304
- Branch:
- main
- Dev Joke
- Почему Prometheus не пришёл на вечеринку? Его заблокировал firewall
Часть потока:
Разработка: borisovai-admin