SSO сломан после сборки со стабильной версией v3.3.3

После пересборки сегодня с версией 3.3.3 (последняя стабильная версия, выпущенная несколько дней назад), SSO перестал работать. Пользователи, уже вошедшие в систему, пока функционируют нормально, но новые сессии завершают процесс SSO с ошибкой:

Время ожидания входа в учётную запись истекло, пожалуйста, попробуйте войти снова.

Включение verbose discourse connect logging показывает:

Подробный лог SSO: Nonce неверен, был сгенерирован в другой сессии браузера или истёк.

Однако ничего в нашем потоке SSO не менялось в последние годы. Часы между серверами синхронизированы.

С другой стороны, мы совсем недавно обновились до версии 3.3.3 (с 3.3.2), которая включает исправления безопасности, связанные с Discourse Connect, что может быть связано с проблемой.

Маловероятно, но пересборка проводилась для включения CDN. Однако я уже откатил все эти изменения, и проблема с SSO сохраняется.

Есть ли какие-либо советы по дальнейшей отладке этой проблемы?

После нескольких пересборок мне удалось снова заставить SSO работать, вернув его к версии 3.3.2, так что, похоже, в версии 3.3.3 было внесено изменение, которое нарушило поддержку SSO.

Я бегло просмотрел git diff v3.3.2 v3.3.3, и ничего очевидного не бросилось в глаза, но там есть изменения, связанные с Discourse Connect.

Однако я подозреваю, что это начнет затрагивать всё больше людей по мере перехода на версию 3.3.3, когда сеансы пользователей начнут истекать и не смогут обновляться. Возможно, стоит более внимательно изучить это тем, кто хорошо знает код, особенно процесс SSO? /cc @sam

PS: Не уверен, что это может быть важно: я обновился до версии 3.3.3 более суток назад, но проблемы, похоже, возникли только вскоре после пересборки через консоль несколько часов назад (для включения CDN, но отмена этого не исправила SSO).

Разве 3.3.3 не немного устарела?

Да, в том смысле, что большинство пользователей используют ветку tests-passed, но нет в том смысле, что это последний релиз стабильной ветки, выпущенный на этой неделе: 3.3.3: Security and maintenance release

Это маловероятно, но возможно ли, что вы генерируете nonce в другой сессии браузера? Например, осуществляя запросы SSO с бэкенда вашего приложения, вместо того чтобы пользователи проходили процесс SSO с помощью перенаправлений в браузере?

Существует скрытая настройка сайта с именем discourse_connect_csrf_protection, которая по умолчанию включена. Чтобы разрешить запросы SSO, выполняемые вне сессии пользователя, её необходимо отключить.

Я предполагаю, что эта настройка присутствовала в версии 3.3.2, но возможно, она была добавлена позже.

Это не так — у нас довольно стандартная реализация того, что описано по ссылке Setup DiscourseConnect - Official Single-Sign-On for Discourse (sso), с соблюдением всех перенаправлений. Она работает без сбоев уже несколько лет, и мы её не трогали.

Хотя мы не делаем ничего необычного в рамках SSO, я всё же попробовал отключить эту настройку через консоль Rails. Единственный эффект заключался в том, что исчезло сообщение об ошибке: когда провайдер SSO перенаправлял обратно в Discourse, вместо ошибки «Account login timed out, please try logging in again.» (Время входа истекло, попробуйте войти снова) не отображалось вообще никакого сообщения — ни ошибки, ни чего-либо ещё. К сожалению, пользователь всё равно оставался разлогиненным.

Я тоже пытаюсь ухватиться за соломинку, так как ситуация довольно странная. Мне кажется, что тот факт, что проблема не проявилась сразу после первоначального обновления до версии 3.3.3 через веб-интерфейс, а возникла лишь (~36 часов) позже после пересборки через консоль, может быть подсказкой, но я недостаточно хорошо знаю различия между этими двумя процессами.

Я снова обновился до версии 3.3.3, и проблема проявилась немедленно. Возврат к версии 3.3.2 снова сделал SSO рабочим.

Я подозреваю, что проблема здесь не в исправлении безопасности DiscourseConnect, а в изменении nginx. На tests-passed нам пришлось сделать дополнительное исправление в четверг, так как оно вызывало проблемы в некоторых окружениях, и другой пользователь на GitHub отметил проблемы с CSRF.

У меня уже есть готовый бэкпорт для этого: FIX: Simplify nginx config change (#30383) by pmusaraj · Pull Request #30410 · discourse/discourse · GitHub, он должен быть слит в ближайшее время (как только кто-то из команды его одобрит, хотя для большинства людей сейчас воскресенье). Вы можете попробовать эту ветку с вашей настройкой SSO, @mentalstring.

Рад сообщить, что это сработало! :tada:

Благодарю вас за то, что нашли время разобраться в этом, особенно в выходные, учитывая, что и stable, и SSO — довольно нишевые темы. Но надеюсь, это поможет и другим. Спасибо!

Я буду следить за тем, чтобы ваш PR был слит.