【问题标题】:OAuth2 Authorization Code Flow - exchange authorization code on Frontend VS Backend? [closed]OAuth2 授权代码流程 - 在前端 VS 后端交换授权代码? [关闭]
【发布时间】:2020-10-08 20:33:18
【问题描述】:

我正在使用 Angular 前端和 Java/Spring-Backend 开发应用程序。为了登录我们的后端,我们使用 Oauth2 Authorization Code Flow with PKCEOpen ID Connect

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

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

现在我读了很多书,但似乎无法理解其中的全部含义。在我看来,让客户端/前端这样做更安全。但另一方面,后端实际上是受信任的,因此在这种情况下我们实际上可以使用 client_secret。

现在的问题是:这两种情况都被认为是安全的吗?或者被认为更安全,如果是这样:为什么?

提前致谢

*编辑:澄清一下——我们实际上并不需要访问另一个资源服务器,用例是我们只想通过我们自己的后端安全地进行身份验证 strong> - 一旦通过身份验证,我们无论如何都会切换到会话 cookie,因此我们根本不会将 access_token 存储在任何地方

【问题讨论】:

    标签: oauth-2.0 oauth openid-connect


    【解决方案1】:

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

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

    另一个参考是:

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

    是的!我认为经典的错误是让 JavaScript 接触你的令牌。知道令牌仅在后端处理,您晚上会睡得更好。此外,更少的安全复杂性和您必须掌握和理解的东西! 我们必须与复杂性作斗争!

    【讨论】:

    • 感谢您的快速回答和链接。是一个很好的芦苇,但似乎并没有完全涵盖我们的案例,因为案例假设我们想要与资源服务器交谈。事实并非如此。实际上我们真的想用它来验证我们自己的后端并在验证后切换到常规会话,所以我们根本不需要存储 access_token(因为我们在登录后不再需要它) - 我会更新我的问题以澄清这一点
    • 更新了我的答案,只需将浏览器客户端与令牌屏蔽!
    • 我现在阅读了更多内容。我猜我们真正在做的是 6.3 - 在这种情况下,我们的后端是资源服务器!我真的应该停止将我们的应用程序视为一个单独的包,因为现在我们的前端和后端之间存在明显的区别。 6.3 似乎 100% 符合我们的用例,这确实让我相信我的使用方式很好 - 或者我错过了什么?
    • 哦,感谢您的更新。没有考虑到这一点。虽然我们现在没有存储 access_token,但客户端仍然必须至少处理一次 access_token - 也许这就是使第二个选择更好的原因?哦,伙计,我的头已经在冒烟了:)
    • 在我的答案末尾添加了一段,这是否使答案可以接受?
    【解决方案2】:

    实际授权码只能使用一次,不管是从前端还是后端发送。

    这里有两种常见的模型:

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

    如果您想将令牌排除在浏览器之外并使用仅 HTTP cookie 作为后端凭据,则使用此选项:

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

    挑战是:

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

    选项 2:SPA 模式

    这是您正在使用的跨域模型,并且在技术上更简单::

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

    挑战是:

    • 如果您的安全性存在漏洞,它们将更容易被利用,因为用户可以更轻松地看到自己的令牌
    • 在此模型中,令牌更新和交叉表导航方面比较棘手。

    因素

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

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

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

    我的资源

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

    虽然不是每个人都同意我的观点。有时在软件中有多种解决方案。重要的是涵盖了安全威胁。您可以使用任一解决方案来做到这一点。

    【讨论】:

      【解决方案3】:

      当您从客户端调用令牌时,它不是授权流程,而是隐式流程,当您没有后端时可以使用它,当您有后端时,您始终应该使用您提到的授权代码流程.你可以了解更多关于openid流here.

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

      【讨论】:

      • 我们没有使用隐式流程,它基本上会“合二为一”(例如,一个检索 access_token 的步骤,而不是使用两个单独的步骤)。
      • 如果您愿意,可以在浏览器中 100% 运行授权流程。但我不会推荐它。
      【解决方案4】:

      使用 PKCE 发送客户端调用是新技术,它被认为是安全的,但绝对授权代码流是后端更好的选择。

      【讨论】:

      • PKCE 仅适用于授权码流。 PKCE 是今天必须避免的安全问题。
      猜你喜欢
      • 1970-01-01
      • 2018-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-31
      • 2021-12-22
      • 2015-04-17
      • 2017-02-25
      相关资源
      最近更新 更多