使用OAuth 2进行单点注销

Jam*_*mes 11 oauth logout oauth-2.0 spring-security-oauth2

我们刚刚讨论了使用OAuth 2时的登录和注销行为.假设我们有两个webapp 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的有效用例吗?您如何以不同方式实施单点注销?

Dav*_*yer 7

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

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

通常,并不总是希望从OAuth2客户端应用程序系统中进行单点注销 - 用户可能认为他们已登录到单独的系统,这些系统恰好为他们进行了身份验证,而实际上并不需要单一的签名体验(例如,如果我退出一个Facebook用户提供的应用程序,我不希望退出我的时间轴).

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

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

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