重建后使用稳定版v3.3.3,SSO失效

今天使用 3.3.3(几天前发布的最新稳定版)重新构建后,SSO 停止工作了。目前已登录用户仍然正常,但新会话的 SSO 流程会以以下错误结束:

账户登录超时,请重试登录。

启用 verbose discourse connect logging 显示:

Verbose SSO log: Nonce 不正确,是在不同的浏览器会话中生成的,或者已过期

然而,我们 SSO 流程在过去几年中没有任何变化。服务器之间的时钟是同步的。

另一方面,我们最近已从 3.3.2 更新到 3.3.3,其中包含与 Discourse Connect 相关的 安全修复,这可能有关。

不太可能相关,但重新构建是为了启用 CDN。但我已经撤销了所有这些更改,SSO 问题仍然存在。

有什么方法可以进一步调试这个问题吗?

经过几次重建,我通过将其固定回 v3.3.2 成功地使 SSO 再次工作,因此 v3.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 时,没有出现 账户登录超时,请重试登录。 错误,而是没有任何消息(错误消息或其他)——但遗憾的是,仍然是未登录状态。

我也在胡乱猜测,因为这很奇怪。我认为,问题在我们最初通过 Web 界面更新到 3.3.3 时没有出现,而是在大约 36 小时后通过控制台重建才出现,这可能是一个线索,但我对两者之间的差异了解不够。

我再次尝试升级到 3.3.3,问题立即出现。切换回 3.3.2 后,SSO 又可以正常工作了。

我怀疑问题不在于 DiscourseConnect 安全修复,而在于 nginx 的更改。在 tests-passed 上,我们周四不得不进行后续操作,因为它在某些环境中引起了问题,并且 Github 上的另一位用户指出了 CSRF 问题。

我已经准备好了一个回溯移植:https://github.com/discourse/discourse/pull/30410,它应该很快就会被合并(一旦团队中的某个人批准它,尽管对大多数人来说现在是周日)。欢迎您尝试使用您的 SSO 设置 @mentalstring 提供的那个分支。

很高兴地报告这招奏效了!:tada:

感谢您花时间对此进行研究,尤其是在周末,并且考虑到 stable 和 SSO 都有些小众,但希望它也能帮助到其他人。谢谢!

我会关注 PR 的合并。