如何在 Kong 的顶部添加一个 API with oauth2

How to add an API with oauth2 on the top of Kong

我正在尝试使用 Kong 的 oauth2 授权插件在顶部 kong 添加一个 API。步骤 我已经按照他们的 Kong documentation :

我从上面的步骤中得到了 client_id、client_secret、provision_key 等,但我想知道我是否需要在我这边创建 oauth2 服务器或配置 kong 本身它在他们的末端,我们只需要调用他们的端点。 我正在 laravel.

构建我的 APIs

我认为我们对 Gitter 的讨论非常简短,我已经说过这取决于您的用例。我将简要介绍典型用例,以及您需要哪种额外实现的地方。

机器对机器通信

如果您需要两个系统从后端相互通信,并且这些系统相互信任,您可以使用 OAuth2 "Client Credentials Flow"。在这种情况下,不涉及 "end user" 身份,只涉及明确相互信任的两个系统。

对于这种情况,Kong 就是您所需要的一切 - 您只需询问 Kong 的 API 令牌端点(<address of kong>:8443/your_api/oauth2/token 对于基于 URI 的路由,或者 fqdn.of.kong:8443/oauth2/token 如果您使用主机基于路由)使用您的客户端 ID 和密钥获取访问令牌,您将获得一个回报。

示例:

curl --insecure -d 'grant_type=client_credentials&client_id=<...>&client_secret=<..>' https://<address of kong>:8443/your_api/oauth2_token

您的后端服务将获得一些额外的 headers 注入,例如映射到您在 Kong 中创建的消费者的 X-Consumer-IdX-Custom-ConsumerId

具有最终用户上下文的机密 Web 应用程序

如果您需要从机密(=经典)网络应用程序中使用您的 API,并且每次调用都需要有最终用户上下文,您可能需要使用 OAuth2 "Authorization Code Grant".在这种情况下,您还需要一个需要自己实现的授权服务器。

授权服务器的任务是建立最终用户身份(请注意:这是 不是 在 OAuth2 中指定的,这是如何完成的,由您决定;您可以与其他一些 IdP 联合,你可以询问用户名和密码,...) 然后决定用户在访问 API 时获得哪些权限 (="scopes")。这完全取决于您,以及您的业务逻辑的一部分如何决定这一点。

流程是这样的:

  1. 您(重新)将用户定向到授权服务器的网页
  2. AS 验证用户(通过任何方式)并决定范围(通过任何其他方式)
  3. AS 在两个不同的层面上与 Kong 对话

    • 通过 Kong Admin API,检索所需 API
    • provision_key
    • 通过 [/your_api]/oauth2/authorize 端点,在经过身份验证的用户及其范围(scopeauthenticated_userid);要调用此终点,您将需要 response_type=codeclient_idclient_secretprovision_keyauthenticated_userid(任何合适的)和可选的 scope (如果要使用它,还需要在 API 上定义范围)
  4. 如果成功,AS 将使用由 Kong

  5. 编辑的重定向 URI return 重定向回 Web 应用程序
  6. Web 应用使用 grant_type=code
  7. 调用 Kong 的 [/your_api]/oauth2/token 端点及其 client_idclient_secretcode

现在您将拥有一个访问令牌(和一个刷新令牌),它允许您的 Web 应用程序代表经过身份验证的用户访问 API .

Authorization Server 必须由您实现;这不是超级复杂,但您仍然需要确保您知道如何对用户进行身份验证,and/or 如何将其委托给其他 IdP。

Public 具有最终用户上下文的客户端(单页应用程序)

如果您需要从单页应用程序(例如从 Angular 应用程序或类似应用程序)访问 API,您应该查看 OAuth2 "Implicit Flow",它是比授权代码授予更简单的流程,但它有其他缺点,比如不能使用刷新令牌。

此流程按以下方式工作:

  1. 就像授予授权码一样,您将用户重定向到授权服务器
  2. AS 建立身份并决定范围(再一次,这取决于你)
  3. AS 调用授权端点,就像使用授权码授予一样,但这次使用 response_type=token
  4. Kong,如果成功,将return一个已经包含令牌
  5. 的重定向URI
  6. AS 使用来自 Kong 的重定向 URI 重定向回 SPA,Kong 在 URI 的 "fragment" 中具有访问令牌(例如 https://your.app.com/#access_token=<...>&token_type=bearer&...

您的 SPA 现在可以使用访问令牌访问 API,就像授权码授予一样,代表经过身份验证的用户

这种方法的缺点是您不能(那样)轻松地刷新令牌,而且它的安全性不如授权码授予。但是处理 SPA,没有很多其他安全的方法来委托访问它。

移动应用程序

我想在这里触及的最后一个场景是移动应用程序,例如 Android 或 iOS 应用程序。对于这些,最后一个 OAuth2 流程,可以使用 "Resource Owner Password Grant"。简而言之,通过此授权,您可以将实际用户凭据(用户名和密码)与访问令牌和刷新令牌进行交换,这样您就不必存储e 移动设备上的用户名和密码暂时不止。

此流程还需要一个授权服务器才能与 Kong 一起使用,尽管这次不那么复杂,尽管您必须实现一个额外的 token 端点(除了 Kong 具有的那个端点之外) ),这在 Kong 文档中没有得到理想的描述。

它会像这样:

  1. 移动应用程序使用其 client_id(不是秘密,秘密不应与应用程序一起部署)、用户名和密码来调用授权服务器的令牌端点
  2. 授权服务器检查用户名和密码(通过任何方式,你知道这个故事)并决定范围(...)
  3. AS 再次通过管理员 API 与 Kong 对话,为提供的 client_id 获取 client_secret 并为所需的 API[获取 provision_key
  4. AS向Kong的token端点发出调用[/your_api]/oauth2/token,像这样:

    curl --insecure -d 'grant_type=password&provision_key=<...>&client_id=<...>&client_secret=<...>&authenticated_userid=<...>&scope=' https://:8443/your_api/oauth2/token

请注意,此调用包含用户名和密码;这些不属于这里,您必须根据自己的身份来源检查用户名和密码,Kong 不会帮助您。

此调用应该 return 一个访问令牌和一个刷新令牌,然后您将它们(尽可能安全地)存储在您的设备上。这些替换用户名和密码,不得存储在设备上。访问令牌可以与其他最终用户上下文流(授权代码授予、隐式授予)一样用于代表经过身份验证的用户访问 API .

将 Kong 与 OAuth2 一起使用是棘手且复杂的,但 Kong 确实可以帮助解决这个问题并解决您的问题。