【问题标题】:Single sign off using OAuth 2使用 OAuth 2 单点注销
【发布时间】:2014-12-30 08:20:05
【问题描述】:

我们刚刚讨论了使用 OAuth 2 时的登录和注销行为。假设我们有两个 Web 应用程序 AB 使用一个 OAuth 提供程序 O(使用 spring-security-oauth2 堆栈构建)。

当您想登录A 时,您会被重定向到O,输入您的凭据,在O 上获得一个会话,使用访问令牌重定向回A,并在@ 上创建一个会话987654330@也一样。

现在,当您想登录 B 时,您会被重定向到 O,并直接将令牌发送回 B,因为您在 O 上仍然有一个有效的 sesison,并且在 B 上创建了一个会话以及(无需再次输入您的凭据)。

这解决了我们的单点登录问题。

现在的一个要求是,当您从A B 注销时,您始终会从两个/所有应用程序中注销(单次注销)。

我们的想法是:

  • 使用当前会话 id 增强访问令牌
  • 如果应用程序AB 想要注销用户,它们会将他重定向到O 的注销页面
  • 如果用户从O 注销,属于O 上当前会话的所有访问令牌都将被删除,用户将被重定向回AB
  • AB 上的会话被破坏
  • AB 在每个请求上检查他们的 OAuth 访问令牌的有效性,如果令牌不再有效,则销毁他们的会话

您认为这是 OAuth 2 的有效用例吗?您将如何以不同的方式实施单点注销?

【问题讨论】:

  • OpenID 最近添加了两个处理单点注销的新规范:openid.net/specs/openid-connect-logout-1_0.htmlopenid.net/specs/openid-connect-backchannel-1_0.html 这些比 OpenID 连接的会话管理方法更容易处理。
  • 嗨,James,我们有类似的要求,希望收到您的来信。您是采用这种方法还是找到其他更好的解决方案?
  • 由于我们目前在同一个域上运行所有应用程序,我们现在使用共享 cookie 来共享会话并处理单点注销。 OAuth 提供者还具有 /end_session 端点,应用程序可以调用该端点以进行正确的注销。为了防止 CSRF 攻击,end_session 端点需要一个有效的签名 JWT 令牌作为查询参数传递。

标签: oauth oauth-2.0 logout spring-security-oauth2


【解决方案1】:

这个问题没有明确答案的原因是,这完全取决于您对用户体验的偏好,以及您信任和/或控制应用和服务器的程度。

我认为您可以通过多种方式做到这一点,并且您的建议绝对可行。我之所以批评它,只是因为 a)您使用 OAuth 令牌作为会话令牌,它们实际上并不是一回事,并且 b)“在每个请求上检查其 OAuth 访问令牌的有效性”部分是有点模糊,我怀疑用户体验可能会受到影响。

一般来说,从 OAuth2 客户端应用程序系统进行单点注销并不总是可取的 - 用户可能认为他们登录到单独的系统,而这些系统恰好为他们方便地进行身份验证,而实际上并不需要单点登录退出体验(例如,如果我退出一个 Facebook 用户提供的应用程序,我预计不会退出我的时间线)。

如果您确实需要单点注销并且您的所有应用都在同一个域中,您可以让它们共享一个会话 cookie,其范围限定为它们共享的域。如果其他应用共享同一个域并且可能不想参与单点登录/注销行为,或者如果您可能不信任它们将 cookie 保密,这将是危险的。

使用 Spring Session,您可以更加复杂,并且仅在您信任的应用程序之间共享会话令牌(因为您只向它们提供对会话存储的访问权限)。这可能会非常有效,如果我能控制所有移动部件,我可能会在你的位置上这样做。

查看OpenID Connect Session Management Spec 看看那里是否有任何想法可能会有所帮助。肯定有身份令牌的概念(与访问令牌不同)。我认为他们建议在浏览器中使用 iframe 中的脚本进行验证检查,这看起来非常难看,但也许真的没有更好的方法。如果您喜欢这个想法,那么您可以使用普通会话 cookie 做同样的事情(可能不需要完整的 OIDC)。

【讨论】:

    猜你喜欢
    • 2014-06-07
    • 1970-01-01
    • 2021-01-18
    • 1970-01-01
    • 1970-01-01
    • 2015-03-19
    • 2014-03-05
    • 2011-02-15
    • 2017-08-21
    相关资源
    最近更新 更多