确保所有 http 请求都通过我的 nginx api 网关

Posted

技术标签:

【中文标题】确保所有 http 请求都通过我的 nginx api 网关【英文标题】:Making sure all http requests go through my nginx api gateway 【发布时间】:2021-09-04 00:18:56 【问题描述】:

我正在设计一个基于 nginx 的 API 网关,其中包含一些身份验证和授权中间件,但我不确定如何强制请求通过 APIGW。

因此,apigw 将使用用户生成的 JWT 接收 HTTP 请求。如果 JWT 有效,我想验证是否允许用户访问 API(通过 ip 黑名单、客户端代理黑名单和用户权限),如果是,则将请求代理到后端服务器并将 jwt 授权标头添加到请求发送到后端服务器。

我的问题是,在我当前的网络设计(不受我控制)中,我无法阻止用户在不通过 apigw 的情况下直接访问后端服务器。

所以我的问题是:如何确保后端服务器收到的 http 请求仅来自 api 网关?

我有几个解决方案,但我想让解决方案尽可能简单,并希望对这些想法提供一些意见:

    在后端应用程序中,我可以将仅来自 apigw IP 地址的请求列入白名单。 这个问题是我的apigw没有静态ip地址

    我可以向 apigw 添加客户端证书,并向后端应用程序验证请求实际上来自 apigw。 这样做的问题是后端必须可以使用我不想设置的 ssl / tls 访问,并且后端应用程序必须添加一些额外的逻辑来验证客户端证书

    我可以添加一个类似于 amazon s3 身份验证的身份验证标头,用于对请求 + 时间戳进行签名。 这似乎是一个不错的选择,但除了验证请求附带的 jwt 之外,它还需要后端验证此签名。 此外,AWS 令牌和 JWT 都使用授权标头发送,因此我必须在替代自定义标头(即“Authorization2”)上发送 AWS 令牌

    我可以获取用户发送的 JWT 并使用仅 APIGW 知道的附加私钥将其退出。后端应用验证 JWT 时,会使用 apigw 提供的公钥(而不是原来的公钥)。

到目前为止,我最赞成退出 JWT 的解决方案 4,因为:

它不需要后端应用程序上的任何额外逻辑,因为它已经验证了 JWT。它只需将公钥更改为 APIGW 之一。

这允许我将有关用户的额外属性注入 JWT(例如从其他来源收集的额外权限)

这让我可以缩短令牌的过期时间以避免重放攻击。客户端 JWT 仍然可以有一个正常的过期时间(例如 1 小时),但是每个发送到后端服务器的 JWT 可以从发送请求开始有 60 秒的过期时间。这样,请求最多只能在原始请求后 60 秒内重播。

那么您对此有何看法?我知道没有正确的答案,但您认为哪种解决方案最有效?

【问题讨论】:

【参考方案1】:

您想要在第 4 项中执行的操作实际上是 Token Exchange,但您将使用您的 API GW 作为执行交换的授权服务器。实现您的需求似乎是一个公平的选择。另一种选择可能是嵌入令牌 - 您的 GW 可以发布新的访问令牌并将原始令牌嵌入其中。然后,您仍然允许您的后端对发送到 API GW 的原始令牌进行操作,但只接受包含在 GW 发出的 JWT 中的令牌的请求。您可以查看我写的 Token Sharing Approaches 文章以了解有关这些技术的更多信息。

【讨论】:

篦条文章!我肯定会在我的 api 网关中实现令牌交换。

以上是关于确保所有 http 请求都通过我的 nginx api 网关的主要内容,如果未能解决你的问题,请参考以下文章

AJAX CORS http 请求 nginx 拒绝

nginx中实现把所有http的请求都重定向到https

nginx将http请求代理为https请求

Centos7.5 下Nginx配置SSL支持https访问。

nginx实现TCP转发

通过Nginx部署Django(基于ubuntu)