BuzzFeed是如何基于OAuth实现集中的单点登录的?


BuzzFeed过去一直使用oauth2_proxy,这个解决方案很可靠,但它缺乏集中的方式让他们的用户登录,这为不断发展的平台带来了一些挑战。所以他们做了任何优秀工程师都会做的事情:在开源中寻找其他现有的、经过测试的解决方案。然而,虽然他们从同行那里听说这是一个常见的问题,但从未找到符合他们规格的东西。因此,他们创造了sso这个开源项目,共享出他们的集中式认证代理,也就是单点登录模块,下面是原文大意提炼:

作为运营商,管理auth代理服务的激增证明是困难的。关键安全修复需要超过70个补丁和部署,而不仅仅是一个。审计和控制跨服务的访问也是一项持续的挑战。为了解决这个问题,我们需要找到一种集中访问和管理的方法。这也将为最终用户创造更愉快的体验,最终用户在当前状态下需要单独登录到每个服务。在理想情况下,用户可以执行单点登录,并在配置的时间跨度内访问所有授权服务。

我们对这些难点的解决方案是sso,是对中央认证服务([url=https://en.wikipedia.org/wiki/Central_Authentication_Service]CAS)[/url]协议的OAu th2友好改编。允许我们用单一的集中式系统取代每项服务的登录,提供无缝,安全的单点登录体验,轻松审核,丰富的测量方式和无痛的开发人员体验。

我们的实现是由两个服务,sso-auth并且sso-proxy,协作执行两个嵌套的认证流程和代理请求。

SSO-AUTH
sso-auth充当中央认证服务,引导用户通过与第三方提供商(例如,Google)的认证流程。它使用第三方提供商的组API(例如,Google网上论坛)为授权提供简单的管理用户体验。

SSO-PROXY
 sso-proxy类似sso-auth提供的OAuth流程,但sso-auth作为它的身份认证提供程序。在完成流程后,它将请求代理回到它的上游。此外,它签署请求,为上游提供认证机制 ,认证来自sso-proxy的 请求。
无论sso-auth和sso-proxy都长时间可以加密存储用户会话信息在Cookies中,但sso-proxy透明地重新验证用户的会话,sso-auth是有一个短的、可配置的时间间隔,从而保证认证和授权更改能够快速传播。

认证流程:

验证权限的流程:

当最终用户访问内部资源时,例如cms.example.com:

  • sso-proxy 首先尝试让通过认证已经存储会话到cookie的客户端来认证用户。
    1. 如果cookie不存在或已达到刷新截止日期,sso-proxy将和sso-auth一起开始一个认证流程,将用户重定向到auth.example.com开始这个新流程.
      • sso-auth 检查其会话cookie以查看它是否存在以及它是否仍然有效。[list=1]
      • 如果cookie不存在或无效,它会将用户重定向到第三方提供程序进行身份认证,并将会话信息存储在会话cookie中。
      • 如果流程成功,sso-proxy则从sso-auth认证代码接收回调并将其交换为访问令牌,然后执行对服务器的API调用以检索有关用户的授权信息。
  • 如果它是有效的cookie,则该请求将被代理到上游。

    其他备选方案
    我们之前考虑了几种替代方法。比如像Keycloak,但我们最终觉得从现有的分布式oauth2_proxy实例集群迁移到集中式集合更容易。我们也不相信有必要引入数据库来满足我们的要求,Keycloak依赖于数据库。无状态和云原生系统更易于部署。此外,oauth2_proxy 使得基于OAuth的解决方案比SAML更加自然。