我们刚刚讨论了使用 OAuth 2 时的登录和注销行为。假设我们有两个 web 应用程序 A
和 B
使用一个 OAuth 提供程序 O
(使用 spring-security-oauth2 堆栈构建)。
当您想登录A
你被重定向到 O
,输入您的凭据,在 O
上获得 session ,重定向回 A
使用访问 token 并在 A
上创建 session 以及。
现在当你想登录 B
你被重定向到 O
, 直接将 token 带回 B,因为您在 O
上仍然有一个有效的 session 。并在 B
上创建了一个 session 以及(无需再次输入您的凭据)。
这解决了我们的单点登录问题。
现在的要求是,当从 A
注销时或 B
您始终从两个/所有应用程序中注销(单点注销)。
我们的想法是:
A
或 B
想要注销用户,他们将他重定向到O
的注销页面O
注销,属于 O
上当前 session 的所有访问 token 被删除,用户被重定向回 A
或 B
A
上的 session 或 B
被摧毁 A
和 B
检查每个请求的 OAuth 访问 token 的有效性,如果 token 不再有效,则销毁其 session 您认为这是 OAuth 2 的有效用例吗?您将如何以不同的方式实现单点注销?
最佳答案
这个问题没有明确答案的原因是,这完全取决于您对用户体验的偏好,以及您信任和/或控制应用程序和服务器的程度。
我认为有几种方法可以做到,你的建议绝对可行。我会批评它只是因为 a) 您使用 OAuth token 作为 session token ,而它们实际上并不是一回事,并且 b) “检查每个请求上的 OAuth 访问 token 的有效性”部分是有点含糊,我怀疑用户体验可能会受到影响。
一般来说,从 OAuth2 客户端应用程序系统进行单点注销并不总是可取的 - 用户可能认为他们登录到单独的系统,这恰好为他们方便地进行了身份验证,而实际上并不想要单点注销体验(例如,如果我退出一个 Facebook 用户提供的应用程序,我不希望退出我的时间线)。
如果您确实需要单点注销并且您的所有应用程序都在同一个域中,您可以让它们共享一个 session cookie,其范围限定为它们共享的域。如果其他应用程序共享同一个域并且可能不想参与单点登录/关闭行为,或者您可能不信任他们将 cookie 保密,这将是危险的。
使用 Spring Session,您可以更加复杂,并且仅在您信任的应用程序之间共享 session token (因为您只向它们提供对 session 存储的访问权限)。这可能会非常有效,如果我可以控制所有移动部件,我可能会在你的位置上这样做。
查看 OpenID Connect Session Management Spec 可能会有所帮助看看有没有什么想法。肯定有身份 token 的概念(与访问 token 不同)。我认为他们建议使用 iframe 中的脚本在浏览器中进行验证检查,这看起来非常难看,但也许真的没有更好的方法。如果你喜欢这个想法,那么你可以用普通的 session cookie 做同样的事情(可能不需要完整的 OIDC)。
关于oauth - 使用 OAuth 2 进行单点注销,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26718274/