DiscourseConnect 流不再工作

自从从 DiscourseSSO 升级到 DiscourseConnect 后,我们的 SSO 集成已停止工作。

我们的设置可能比较特殊:SSO 可以从多个应用程序发起,而非单一应用。我们的软件既支持本地部署,也支持云端的多种租户模式。每个租户实例的软件都包含一个指向我们 Discourse 社区的 SSO 链接。这意味着我们可以从(例如)tenant1.ourcompany.comsoftware.tenant2.comsomething.else.com 等近一千个不同的地方发起 SSO。

我们并非在所有租户中使用单一的集中式身份提供商;每个租户可以使用自己的 IDP 解决方案(如 Google、O365、AD、Okta 等)。在服务器端,我们已部署了相关流程和缓解措施,以防止账户被盗用。

不幸的是,我们的这一方案在最近的 Discourse 更新中似乎已无法正常工作。(感谢 此提交 带来的影响。)从技术角度来看,原本正常的工作流程如下:

  • 我们的后端通过 API 从 Discourse 获取 nonce 和 SSO 详情
  • Discourse 会发送一个包含 SSO 有效载荷的 301 重定向,返回到我们指定的单一地址
  • 该服务器配置为忽略 301 重定向(以避免 nonce 错误)。相反,它会解析 Location 头,解码 base64 值,获取 nonce,生成 SSO 有效载荷,使用 SSO 密钥对其进行签名,然后将用户引导至 SSO 登录 URL。

似乎 nonce 的机制已更改,现在它绑定到浏览器会话中(以防止 CSRF 攻击)。这意味着当我们尝试上述流程时,由于在将用户重定向回 Discourse 时,客户端浏览器缺少包含 nonce 的 _forum_session Cookie,因此我们会收到“nonce 已过期”的错误提示。

是否可以将此 CSRF 保护设为可选?也就是说,能否新增一个 enable_secure_nonce 设置,允许我们将其设置为 false

目前,我们的大部分客户无法访问我们的论坛。我们可能不得不要求他们全部设置密码,同时我们将失去在应用中跟踪论坛通知的能力,这会导致用户参与度下降。:frowning:

2 个赞

是的,传统上我们一直支持针对此类情况设置站点选项。我们可能会将其设为隐藏设置,因为它很难解释清楚,但我确实支持像您这样的特殊情况。之后我们可以在您的实例上启用它。

@david 会查看此事。

7 个赞

现在可以通过 Rails 控制台运行以下命令来禁用该保护功能:

SiteSetting.discourse_connect_csrf_protection=false

仅在您理解并接受由此引入的风险时执行此操作。对于由 discourse.org 托管的用户,请联系我们,我们可以为您更改此设置。

(cc @rysher,他曾提出过类似的请求

9 个赞

此主题已在最后回复后 30 天自动关闭,不再允许新回复。