如何在 Kong 的顶部添加一个 API with oauth2
How to add an API with oauth2 on the top of Kong
我正在尝试使用 Kong 的 oauth2 授权插件在顶部 kong 添加一个 API。步骤
我已经按照他们的 Kong documentation :
- 创建一个 API 并添加 oauth2 插件
- 创建消费者
- 创建应用程序
我从上面的步骤中得到了 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-Id
和 X-Custom-ConsumerId
。
具有最终用户上下文的机密 Web 应用程序
如果您需要从机密(=经典)网络应用程序中使用您的 API,并且每次调用都需要有最终用户上下文,您可能需要使用 OAuth2 "Authorization Code Grant".在这种情况下,您还需要一个需要自己实现的授权服务器。
授权服务器的任务是建立最终用户身份(请注意:这是 不是 在 OAuth2 中指定的,这是如何完成的,由您决定;您可以与其他一些 IdP 联合,你可以询问用户名和密码,...) 然后决定用户在访问 API 时获得哪些权限 (="scopes")。这完全取决于您,以及您的业务逻辑的一部分如何决定这一点。
流程是这样的:
- 您(重新)将用户定向到授权服务器的网页
- AS 验证用户(通过任何方式)并决定范围(通过任何其他方式)
AS 在两个不同的层面上与 Kong 对话
- 通过 Kong Admin API,检索所需 API
的 provision_key
- 通过
[/your_api]/oauth2/authorize
端点,在经过身份验证的用户及其范围(scope
和 authenticated_userid
);要调用此终点,您将需要 response_type=code
、client_id
、client_secret
、provision_key
、authenticated_userid
(任何合适的)和可选的 scope
(如果要使用它,还需要在 API 上定义范围)
如果成功,AS 将使用由 Kong
编辑的重定向 URI return 重定向回 Web 应用程序
- Web 应用使用
grant_type=code
调用 Kong 的 [/your_api]/oauth2/token
端点及其 client_id
、client_secret
和 code
现在您将拥有一个访问令牌(和一个刷新令牌),它允许您的 Web 应用程序代表经过身份验证的用户访问 API .
Authorization Server 必须由您实现;这不是超级复杂,但您仍然需要确保您知道如何对用户进行身份验证,and/or 如何将其委托给其他 IdP。
Public 具有最终用户上下文的客户端(单页应用程序)
如果您需要从单页应用程序(例如从 Angular 应用程序或类似应用程序)访问 API,您应该查看 OAuth2 "Implicit Flow",它是比授权代码授予更简单的流程,但它有其他缺点,比如不能使用刷新令牌。
此流程按以下方式工作:
- 就像授予授权码一样,您将用户重定向到授权服务器
- AS 建立身份并决定范围(再一次,这取决于你)
- AS 调用授权端点,就像使用授权码授予一样,但这次使用
response_type=token
- Kong,如果成功,将return一个已经包含令牌
的重定向URI
- 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 文档中没有得到理想的描述。
它会像这样:
- 移动应用程序使用其
client_id
(不是秘密,秘密不应与应用程序一起部署)、用户名和密码来调用授权服务器的令牌端点
- 授权服务器检查用户名和密码(通过任何方式,你知道这个故事)并决定范围(...)
- AS 再次通过管理员 API 与 Kong 对话,为提供的
client_id
获取 client_secret
并为所需的 API[获取 provision_key
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 确实可以帮助解决这个问题并解决您的问题。
我正在尝试使用 Kong 的 oauth2 授权插件在顶部 kong 添加一个 API。步骤 我已经按照他们的 Kong documentation :
- 创建一个 API 并添加 oauth2 插件
- 创建消费者
- 创建应用程序
我从上面的步骤中得到了 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-Id
和 X-Custom-ConsumerId
。
具有最终用户上下文的机密 Web 应用程序
如果您需要从机密(=经典)网络应用程序中使用您的 API,并且每次调用都需要有最终用户上下文,您可能需要使用 OAuth2 "Authorization Code Grant".在这种情况下,您还需要一个需要自己实现的授权服务器。
授权服务器的任务是建立最终用户身份(请注意:这是 不是 在 OAuth2 中指定的,这是如何完成的,由您决定;您可以与其他一些 IdP 联合,你可以询问用户名和密码,...) 然后决定用户在访问 API 时获得哪些权限 (="scopes")。这完全取决于您,以及您的业务逻辑的一部分如何决定这一点。
流程是这样的:
- 您(重新)将用户定向到授权服务器的网页
- AS 验证用户(通过任何方式)并决定范围(通过任何其他方式)
AS 在两个不同的层面上与 Kong 对话
- 通过 Kong Admin API,检索所需 API 的
- 通过
[/your_api]/oauth2/authorize
端点,在经过身份验证的用户及其范围(scope
和authenticated_userid
);要调用此终点,您将需要response_type=code
、client_id
、client_secret
、provision_key
、authenticated_userid
(任何合适的)和可选的scope
(如果要使用它,还需要在 API 上定义范围)
provision_key
如果成功,AS 将使用由 Kong
编辑的重定向 URI return 重定向回 Web 应用程序
- Web 应用使用
grant_type=code
调用 Kong 的
[/your_api]/oauth2/token
端点及其 client_id
、client_secret
和 code
现在您将拥有一个访问令牌(和一个刷新令牌),它允许您的 Web 应用程序代表经过身份验证的用户访问 API .
Authorization Server 必须由您实现;这不是超级复杂,但您仍然需要确保您知道如何对用户进行身份验证,and/or 如何将其委托给其他 IdP。
Public 具有最终用户上下文的客户端(单页应用程序)
如果您需要从单页应用程序(例如从 Angular 应用程序或类似应用程序)访问 API,您应该查看 OAuth2 "Implicit Flow",它是比授权代码授予更简单的流程,但它有其他缺点,比如不能使用刷新令牌。
此流程按以下方式工作:
- 就像授予授权码一样,您将用户重定向到授权服务器
- AS 建立身份并决定范围(再一次,这取决于你)
- AS 调用授权端点,就像使用授权码授予一样,但这次使用
response_type=token
- Kong,如果成功,将return一个已经包含令牌 的重定向URI
- 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 文档中没有得到理想的描述。
它会像这样:
- 移动应用程序使用其
client_id
(不是秘密,秘密不应与应用程序一起部署)、用户名和密码来调用授权服务器的令牌端点 - 授权服务器检查用户名和密码(通过任何方式,你知道这个故事)并决定范围(...)
- AS 再次通过管理员 API 与 Kong 对话,为提供的
client_id
获取client_secret
并为所需的 API[获取provision_key
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 确实可以帮助解决这个问题并解决您的问题。