什么是一种很好的对微服务友好的刷新令牌安全技术



我有一个OAuth2驱动的授权系统,用于使用Auth-Code流的生态系统中的应用程序。目前,按照我认为的最佳实践,它运行得非常好。我目前的流程可以总结为:

  1. 用户单击应用程序前端的"登录"按钮
  2. 应用程序的后端将用户重定向到参数中具有重定向URI、客户端ID等的Auth Server登录页
  3. 用户登录,身份验证服务器重定向到具有授权代码的后端/身份验证代码端点
  4. 后端使用授权码进行认证,接收接入(JWT)&刷新令牌。它将Refresh令牌存储在自己的数据库中,并将Access令牌作为HTTP-Only cookie返回
  5. 当访问令牌过期时,后端会向身份验证服务器发送刷新令牌以进行刷新

这种方法的问题是它严重依赖于单个后端/单体/etc架构。当访问令牌过期时,有问题的后端应用程序需要能够获得刷新令牌,然后对Auth Server进行刷新。

我对这个体系结构的未来状态的目标是由两个主要关注点驱动的:

  1. 允许将后端拆分为多个微服务,这些微服务都能够对同一JWT进行身份验证
  2. 支持SSO。目前,即使所有用户都通过同一个Auth Server进行管理并使用相同的凭据,他们也需要为登录的每个应用程序分别输入这些凭据

我最初的想法是将刷新处理转移到体系结构的客户端部分。由于所有的应用程序都归我所有,我可以设置一个新的流,用户可以直接使用Auth Server登录,然后将Access(JWT)和Refresh令牌设置为HTTP Only cookie。我的所有应用程序都通过一个域名托管(不同应用程序的根URI路径不同),这一事实进一步支持了这一点。新的令牌结构将决定给定用户可以访问哪些应用程序

我关心的是如何保护刷新令牌客户端。我很可能需要使用Path属性,这取决于我所有的应用程序都在同一个主机名上,正如我所说的,这一点不会改变。

我想这篇文章的重点是,我正在寻找处理这种情况的最佳实践指南。

我们在Curity推荐的基于设计模式的一些想法:

后端和JWTs

相关的API应该能够相互转发JWT访问令牌,如scopes文章中所述。在每个API中验证JWT会导致建议的零信任设置。

后端用于前端

我们推荐一种特殊的方法来实现这一点,重点关注web和API关注点的分离——请参阅关于令牌处理程序模式的代码示例。

令牌刷新通过HTTP Only cookie和客户端重试进行处理。这提供了一个易于管理的无状态解决方案,并且web后端仅为静态内容,例如内容交付网络。不过,它需要部署几个实用程序API组件。

正如您所说,另一种选择是在后端编写代码来存储令牌,这样cookie只包含会话ID。

COOKIES和多个WEB应用程序

在我们的资源中,我们使用反向代理/API网关作为API的入口点,而不是web后端。然后可以通过网关插件管理常见的管道,如将cookie转换为令牌,如本教程所述。

然而,当您有多个web应用程序时,您需要在API请求期间隔离Cookie。因此,每个应用程序都需要自己的API路由。这很尴尬,但这是由于需要使用安全的cookie来实现最佳浏览器安全性。它最好在网关中管理,单独的域或子域通常是最干净的:

  • https://api.brand1.com
  • https://api.brand2.com

然后,每个web团队负责自己的API路由和cookie/CORS/CSRF,而不是API开发人员。

SSO

这应该完全由身份提供程序会话cookie决定,在您浏览应用程序时,该cookie将保持有效。如果你在应用程序还没有安全cookie的情况下显示登录按钮,那么它不会感觉像SSO。让SSO看起来无缝的一种技术是,每个应用程序在还没有应用程序cookie时自动重定向,而不是显示登录按钮。

摘要

答案很长,但最好的解决方案需要分离并非总是显而易见的问题。如果做得好,最终的结果应该是应用程序中的简单代码、正确的安全性和可扩展的架构。

最新更新