自从从 DiscourseSSO 升级到 DiscourseConnect 后,我们的 SSO 集成已停止工作。
我们的设置可能比较特殊:SSO 可以从多个应用程序发起,而非单一应用。我们的软件既支持本地部署,也支持云端的多种租户模式。每个租户实例的软件都包含一个指向我们 Discourse 社区的 SSO 链接。这意味着我们可以从(例如)tenant1.ourcompany.com、software.tenant2.com 或 something.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?
目前,我们的大部分客户无法访问我们的论坛。我们可能不得不要求他们全部设置密码,同时我们将失去在应用中跟踪论坛通知的能力,这会导致用户参与度下降。![]()