如何结合单点注销和无状态身份验证

Posted

技术标签:

【中文标题】如何结合单点注销和无状态身份验证【英文标题】:How to Combine Single Sign Off and Stateless Authentication 【发布时间】:2015-10-27 12:05:04 【问题描述】:

我正在尝试添加基于 SAML 的单点登录/单点注销解决方案,以允许基于 Web 的应用程序的混合生态系统,从而给最终用户留下他们正在与单个应用程序交互的印象。

对此的标准方法似乎是让 IdP 管理用户身份验证(建立 IdP 会话),然后根据需要发出签名的 SAML 登录请求以在每个组件应用程序中建立会话。

可以使用 SAML 单点注销来处理注销,其中,在注销时,IdP 向每个服务提供商发出反向通道调用以使会话无效。

这适用于传统的基于有状态会话的应用程序,但我正在尝试研究如何集成使用无状态 JWT 令牌代替服务器端会话的应用程序。

登录部分的工作原理相同,我们只是发出 JWT 以响应 SAML 登录,而不是建立传统的会话。只需删除 cookie 即可退出单个服务。

但是有什么方法可以实现单点注销流程?我能看到的唯一方法是:

在同一域(或至少子域)上托管所有无状态应用程序 退出时,删除该域的所有无状态身份验证 cookie,而不仅仅是单个应用程序的一个 清除这些 cookie 后,触发 SAML 单点注销流程以处理有状态的应用程序。

有没有更标准的方法来解决这个问题,还是总是手动滚动?

在我的研究中,我发现大量使用无状态令牌进行单点登录,以及使用本地或 SAML Sign Off 等标准在有状态的完整应用程序中使用单点登录的日志。但我找不到比我所描述的在混合环境中将两者结合起来更简单或更标准的方法了。

参考资料:

Single sign off using OAuth 2 - 在滥用 OAuth 时,情况与我所描述的情况类似,但通过建立服务器端状态来验证 OAuth 令牌以实现签名来解决 Transparent user session over several sites (single sign-on + single sign-off) & How to do stateless (session-less) & cookie-less authentication? 很好地描述了我渴望启用的那种无状态身份验证流程,但似乎依赖于共享的服务器端令牌存储或仅依赖于超时而不是显式注销

【问题讨论】:

【参考方案1】:

1 - 身份提供者如何让目标应用程序知道它们不应允许用户登录

在 SAML 中,这是通过在协议中形式化的 Single LogOut (SLO) 实现的。 IdP 可以向目标应用程序发送 SLO 消息,然后目标应用程序可以采取行动。这给我们带来了

2 - 目标应用程序如何阻止用户在收到“有效”JWT 令牌时登录

当应用程序生成 JWT 令牌时,它需要以这样的方式这样做,以便以后可以撤销此令牌。实际上,这意味着通过一些唯一标识符(例如 JWT ID (jti))来跟踪已发行的令牌。如果应用程序通过联系负责管理这些代币的第 3 方来生成代币,那么您希望/坚持让第 3 方代币发行者提供一种撤销代币的方法。

如果应用程序(或第 3 方发行者)无法撤销令牌,那么您仍然可以通过让令牌过期来实现这一点。那是你的穷人的令牌失效解决方案。

【讨论】:

我不太担心令牌继续有效,因为我不(过度)担心撤销,除非用户请求它。我主要担心的是,当用户在共享终端上“注销”时,使用同一浏览器的人无法重新访问他们的会话。虽然您的回答确实解决了吊销问题,但它需要有效会话标识符的共享存储来验证令牌并允许 SAML 注销,这是我希望避免的。感谢您的回答,您已经验证了我的想法,即没有共享状态,选择有限。

以上是关于如何结合单点注销和无状态身份验证的主要内容,如果未能解决你的问题,请参考以下文章

如何管理两个身份验证系统:有状态和无状态(缓存)

如何在 Vue 中设置身份验证状态更改?

Keycloak Angular 2 - 检查身份验证状态 Keycloak 对象

Safari 5.1 基本身份验证注销问题

Devise 的 HTTP 身份验证中断了常规注销

如何注销 Spotify API 身份验证流程演示