内部身份验证令牌颁发的OAuth代码授予流



我需要将React SPA与第三方身份验证提供商集成。此外,我的应用程序将使用我自己的内部JWT进行身份验证,这样除了初始用户身份验证之外,我们就可以与第三方提供商解耦。这也允许我们将自己的自定义索赔添加到JWT中。后端的所有内部API调用都将通过API网关使用内部JWT。我建议的流程如下:

Auth流

  1. 用户在web.acme.com请求我的React应用程序
  2. 应用程序使用受保护的路由来检查用户是否已登录。它通过检查本地/会话存储中是否有JWT来实现这一点,如果是,它会向api.acme.com/authorize的我的身份验证服务发出POST请求,以检查JWT是否有效(200或401响应)
  3. 如果未登录,应用程序将显示一个登录页面。用户单击登录按钮,浏览器加载第三方身份验证提供商foo.com的登录URL
  4. 当用户进行身份验证时,它们被重定向到api.acme.com/login?code=abc123,也就是说,它们现在被重定向到我自己的身份验证服务,并带有访问代码
  5. 我的身份验证服务现在使用访问代码代表用户从foo.com请求访问令牌。当检索到访问令牌时,我的身份验证服务现在发布我自己的内部JWT,其中包含从foo.com令牌中提取的声明以及我自己的附加声明
  6. 身份验证服务将用户重定向回web.acme.com的web应用程序,并包含JWT
  7. React应用程序再次加载并重复步骤(2)。由于JWT现在存在并且有效,因此呈现受保护的路由

问题

  1. 这个流有意义吗?也就是说,它与OAuth 2.0兼容吗?有什么明显的缺陷吗
  2. 是否可以将JWT包括在步骤(6)的重定向中?我的理解是浏览器在重定向时会忽略正文。我希望浏览器被重定向,但也将JWT存储在本地/会话存储中,因此JWT必须在重定向时转发,React应用程序才能接收它。这能做到吗
  1. 它走在正确的轨道上,只是我不确定推荐的浏览器流(授权代码+PKCE)是否通过所有正确的检查实现?在API中实现这一点是非常棘手的。

  2. 要从API重定向回web源并提供JWT,有两个选项:

  • a。在查询字符串中包含JWT,但这样可能会向浏览器和服务器日志显示JWT
  • b。将其设置在一个仅HTTP加密的cookie中,然后重定向到web源,另一个服务器调用可以从中获取JWT

本地存储中的代币

2021年,不建议将代币存储在本地存储中,甚至根本不建议将其存储在浏览器中。当然,你做出的决定应该取决于你的数据的敏感性和你的利益相关者的想法。

短期访问令牌可能还可以,但由于各种攻击向量,即使对良好的输入保护进行了编码,长期刷新令牌也被认为是坏的。这段2021年的视频有更多的细节。

浏览器最近有两个相关的变化:

  • SameSite=strictcookie变得更强,具有内置的CSRF保护,并且在浏览器中被认为比OAuth令牌更安全

  • SPAs的传统OAuth流允许使用来自授权服务器的SSO cookie来获取新的短期访问令牌。但这些现在可能被视为third party,并被删除以防止跟踪(Safari会这样做)。这意味着解决页面重新加载等可用性问题的唯一(非cookie)方法是将刷新令牌存储在本地存储中,从安全角度来看,这被认为是糟糕的。

后端用于前端

因此,SPA应该将刷新令牌存储在仅HTTP加密的安全cookie中,作为其主要凭据。还建议使用高安全性应用程序,以避免在浏览器中访问令牌。

趋势是使用处理SPA令牌并编写安全cookie的东西。一种选择是使用较旧的"web后端"技术,另一种是使用API驱动的方法。

API驱动解决方案

这些Curity资源显示了后一种选择,它与您描述的模式相似:

  • 代码
  • 文档

这里是React安全代码,其中SPA只进行API调用,API从不处理重定向。此处记录了API代表SPA发送的OpenIDConnect消息。

就您的问题2而言,我们通过允许浏览器接收代码,然后将其完整URL发送到API来处理此问题。这使web和API关注点分离,攻击者不能利用它,因为代码必须同时带有PKCE代码验证器和客户端机密才能获得令牌。

摘要

不幸的是,SPA安全性很难,额外的cookie层对web开发人员来说很不方便。

相关内容