12

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

当您想登录时,A您会被重定向到O,输入您的凭据,在那里获得一个会话O,使用访问令牌重定向回,A并且还会创建一个会话A

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

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

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

我们的想法是:

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

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

4

1 回答 1

9

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

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

通常,从 OAuth2 客户端应用程序系统进行单点注销并不总是可取的——用户可能认为他们登录到单独的系统,这些系统恰好为他们方便地进行身份验证,实际上并不想要单点注销体验(例如,如果我退出一个 facebook 用户提供的应用程序,我不希望退出我的时间线)。

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

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

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

于 2014-11-03T18:14:04.267 回答