OAuth2授权代码流程-在前端VS后端上交换授权代码?

时间:2020-10-08 11:31:43

标签: oauth-2.0 oauth openid-connect

我正在使用Angular Frontend和Java / Spring-Backend开发应用程序。为了登录到后端,我们使用带有PKCE的 Oauth2授权代码流 Open ID Connect

当用户导航到受保护的路线时,他将被重定向到其IDP并必须登录。之后,他将以authorization_code作为URL参数返回到redirect_uri。到目前为止,一切都清楚了。

现在我不确定将代码替换为access_token的最佳方法是什么?到目前为止,我已经在客户端(使用JavaScript)中完成了此操作,并使用接收到的JWT进行了进一步的后端调用(在后端,我只是验证了签名),这似乎确实可行。但是在其他项目中,我看到同事实际上使用了后端,就像是代理。因此,他们将authorization_code发送到Java后端,然后后端进行交换。

现在我已经阅读了很多,但似乎无法完全理解它的含义。在我看来,让客户端/前端执行此操作更安全。但是另一方面,后端实际上是受信任的,因此在这种情况下,我们实际上可以使用client_secret。

现在的问题是:两种情况都被认为安全吗?还是一种安全性更高?如果可以,为什么?

预先感谢

* 编辑:只是为了澄清-我们确实不需要访问其他资源服务器,用例是我们只想对自己的后端安全地进行认证-通过身份验证后,我们还是会切换到会话Cookie,因此我们根本不会在任何地方存储access_token

4 个答案:

答案 0 :(得分:1)

实际授权码只能使用一次,因此无论从前端还是后端发送都无所谓。

这里有两种常见的模型:

选项1:Web后端/代理模式

如果您想将令牌保留在浏览器之外,而仅将HTTP cookie用作后端凭据,则使用它:

  • Web后端发布同一域的仅HTTP cookie,并将令牌存储在数据库或cookie本身中
  • Web UI通过首先使用Cookie调用Web后端来进行所有API调用
  • Web后端然后查找令牌并将其转发到API
  • 您需要应对CSRF和XSS等网络威胁

挑战是:

  • 比您想要的复杂得多
  • 一些架构限制

选项2:SPA模式

这是您正在使用的跨域模型,在某种程度上讲在技术上更简单:

  • Web UI通过发送访问令牌来进行API调用
  • 您需要应对XSS之类的威胁,并特别关注确保在浏览器中使用令牌的安全性不亚于cookie的使用
  • 您需要以安全的方式将令牌存储在浏览器中,例如存储在内存中

挑战是:

  • 如果您在安全方面存在漏洞,则由于用户可以更轻松地查看自己的令牌,因此漏洞利用会更容易
  • 在此模型中,令牌更新和交叉表导航方面比较棘手。

因素

这些是做出选择时的主要因素:

  • 安全威胁模型-令牌v cookie和其他因素
  • Web UI的更广泛的体系结构目标
  • 对利益相关者的感知通常是最大的考虑因素

无论您做什么决定,我都建议从需求开始,而不是从特定的技术堆栈开始。

矿山资源

我更喜欢选项2,因为我认为架构选择要好得多,但是需要小心。以下链接有望帮助您了解我如何提出我的首选解决方案:

尽管并非所有人都同意我的看法。有时在软件中有多种解决方案。重要的是要涵盖安全威胁。您可以使用任一解决方案来做到这一点。

答案 1 :(得分:0)

在后端保留令牌始终是一种更安全的方法,因为它可以减少攻击面并使客户端中的代码更简单。

一个好的起点是看一下这个BCP

另一个参考是:

为了简化您的JavaScript,我将在后端进行所有客户端身份验证,并且当后端获得令牌时,再与您的客户端创建会话。这样,JavaScript客户端无需触摸任何令牌。您的内部资源/ API将通过负责该会话的服务进行访问。干净简单! :-)

是的!我认为经典的错误是让JavaScript接触您的令牌。知道令牌仅在后端处理,您将在晚上睡得更好。而且,减少了安全性复杂性,您必须掌握和理解的东西也少了! 我们必须应对复杂性!

答案 2 :(得分:0)

当从客户端调用您的令牌时,它不是授权流,而是隐式流,可以在没有后端的情况下使用,当您有后端时,应始终使用授权代码流(如前所述) 。您可以了解有关openid流here.

的更多信息

授权代码流正在考虑更加安全,因为它使用IDP的反向通道通信(服务器到服务器)接收令牌,而隐式流从浏览器发送请求。

答案 3 :(得分:0)

使用PKCE发送客户呼叫是一项新技术,它被认为是安全的,但肯定地,授权代码流是后端的更好选择。