DiscourseConnect flow больше не работает

После обновления с DiscourseSSO на DiscourseConnect наша интеграция SSO перестала работать.

У нас, вероятно, нетипичная конфигурация: SSO может инициироваться из множества приложений, а не из одного. Наше программное обеспечение можно устанавливать локально или в облаке с поддержкой мульти-арендаторности. Каждый экземпляр арендатора включает ссылку SSO для перехода в наше сообщество Discourse. Это означает, что мы можем инициировать SSO (например) с tenant1.ourcompany.com, software.tenant2.com, something.else.com — почти из тысячи разных мест.

У нас нет единого центрального провайдера идентификации для всех арендаторов; каждый может использовать своё решение IDP (Google, O365, AD, Okta и т. д.). На стороне сервера у нас внедрены процессы и меры защиты от захвата аккаунтов.

К сожалению, наш подход перестал работать в последнем обновлении Discourse. (Спасибо этому коммиту.) С технической точки зрения рабочий процесс выглядел так:

  • Наш бэкенд через API получал nonce и данные SSO из Discourse
  • Discourse отправлял перенаправление 301 с полезной нагрузкой SSO обратно нам по одному конкретному адресу
  • Сервер здесь был настроен игнорировать перенаправление 301 (чтобы избежать ошибок nonce). Вместо этого он парсил заголовок Location, декодировал значения base64, получал nonce, генерировал полезную нагрузку SSO, подписывал её секретом SSO и отправлял пользователя по назначению на URL входа через SSO.

Похоже, что nonce был изменён так, что теперь он привязан к сессии браузера (для защиты от CSRF-атак). Это означает, что когда мы пытаемся выполнить описанный выше процесс, клиентский браузер не имеет куки _forum_session с nonce, когда мы возвращаем его в Discourse, и мы получаем сообщение «nonce истёк».

Возможно ли сделать эту защиту CSRF опциональной? То есть добавить новый параметр enable_secure_nonce, который можно установить в false?

На данный момент большинство наших клиентов не могут получить доступ к нашему форуму, и нам, возможно, придётся заставить всех них настроить пароли, а также мы потеряем возможность отслеживать уведомления форума в нашем приложении — что приведёт к снижению вовлечённости. :frowning:

Да, традиционно мы всегда поддерживали настройки сайта для таких случаев. Вероятно, мы сделаем это скрытой настройкой, так как её очень сложно объяснить, но я поддерживаю это для редких случаев, как ваш. Затем мы сможем включить её на вашем экземпляре.

@david изучит этот вопрос.

Теперь можно отключить защиту через консоль Rails, выполнив команду:

SiteSetting.discourse_connect_csrf_protection=false

Делайте это только в том случае, если вы понимаете и принимаете связанные с этим риски. Если ваш сайт размещён на discourse.org, пожалуйста, свяжитесь с нами, и мы изменим этот параметр за вас.

(копируем @rysher, у которого был аналогичный запрос)