首页 > 解决方案 > 我应该为 PWA + 服务器端应用程序使用哪个 OAuth2 身份验证流程

问题描述

我正在尝试为应用程序选择正确的身份验证流程:

现在我正在使用授权代码授予流程。

我尝试了什么:

您能否告诉我什么 OAuth2 流程适合我的上下文以及为什么?

标签: securityauthenticationoauthoauth-2.0

解决方案


假设(我理解问题的方式):

  • 您拥有并开发前端(Angular 应用程序)和后端(服务器端 REST API)。
  • 您希望将身份验证外包给第 3 方身份提供者。
  • 您希望 Angular 应用程序(客户端)持有令牌并能够在后端(资源服务器)上进行身份验证,并在第 3 方(授权服务器/身份提供者(IdP))上建立您的用户(资源所有者)的身份.

第一,偏题。对于这个用例,OpenId Connect (OIDC) 会更合适,因为它支持标识元素。OAuth2 的重点是授权您的应用在第 3 方执行操作。您想要的是在第 3 方的帮助下建立用户的身份,这就是 OpenId Connect 所做的。

好的,那么哪个流程(OIDC 仍然基于 OAuth2)。

第一个问题是客户端是否被信任在资源服务器上做任何事情,以及它是否可以安全地存储一个秘密。显然不是这样,客户端应用程序不可信,也不能保密。在客户端凭据流中,客户端使用密钥在 IdP 上进行身份验证,以接收资源服务器的令牌。这意味着您的 Angular 应用程序存储了一个密码,用于为您的后端获取令牌,显然不是您想要的。

当信任客户端处理用户凭据时,使用资源所有者密码凭据流。在您的用例中,这并不好,因为实际上这意味着您的 Angular 应用程序将获取用户密码以将其转发给 IdP 以换取令牌。您的客户不应该有权访问用户密码,它是不受信任的。

现在是更有趣的部分。

问题是您的客户端是否有服务器端来安全地保存秘密。如果是这样,授权代码授予很好,因为它允许您的用户在 IdP 上进行身份验证,使用授权代码重定向回来,然后服务器端可以将其交换为要在资源服务器上使用的访问令牌。但是,在这种情况下,您的客户端没有服务器端,据我所知,API资源服务器。所以这对你不利,因为它需要一个客户端密码,而且你不能将它存储在你的 Angular 应用程序中。

这几乎给您留下了隐式流程,您不需要客户端机密,但另一方面,很难执行刷新令牌之类的操作。在您链接到的流程图中,最后一个问题是您的客户是否是 SPA - 就您而言,它是,因此您应该默认使用隐式流程。

这对你来说可能是最安全的模型,因为即使在你的客户端被入侵的情况下,你的用户凭据仍然是安全的(Angular 应用程序永远无法访问)。

但是,您可以对整个事情进行不同的建模,这会大大简化它。

据我所知,您同时拥有客户端和资源服务器,并且资源所有者正在使用客户端,您只想在仍然管理 3rd 方服务中的用户的同时卸载身份验证。

这样看,您的客户端被信任访问用户凭据,并且使用它的用户是资源所有者。因此,您可以使用资源所有者密码流程,用户将其凭据直接输入到 Angular 应用程序中,该应用程序进入 IdP,获取令牌,Angular 只需使用它来访问 API(资源服务器)上的内容。

与隐式流程相比的风险在于,如果 Angular 应用程序被入侵,用户凭据将被泄露给攻击者。您是否愿意接受这种风险完全取决于您。请注意,如果 IdP 是知名服务(例如社交网站),这显然不起作用,因为作为您的用户,我不想将我的社交网站密码提供给您的应用程序。但是,只要您无论如何都管理用户,信任客户端是可以接受的。


推荐阅读