首页 > 解决方案 > API 中不可见的自定义 Origin 标头

问题描述

我有一个应用程序,其中客户端托管在具有 CloudFront 分配的 S3 上。API 位于带有 WAF 的 API 网关后面,客户端向 API 发出 http 请求以获取和发布数据。

我想限制对 API 的访问,使其只能从客户端获得,并且当有人尝试直接访问 API 时它应该返回错误。

诀窍是 API 向第三方公开,因此我不能使用 API Gateway 授权方,因为它们必须具有直接访问权限。

我在 CloudFront 中设置了一个自定义源头 ( My-Secret-Header: 1234567890qwertyuiop),我认为我可以在 WAF 中创建一个规则以允许使用此头的请求(加上基于其他标准的第 3 方,但该部分运行良好,它不是问题),并阻止其他所有内容。

问题是它My-Secret-Header永远不会进入 WAF,并且它不会被添加到源自客户端应用程序的 http 请求中。

我还尝试使用 Lambda@Edge 添加自定义标头,但没有成功。我使用 Lambda@Edge 和event.Records[0].cf.request.origin.s3.customHeaders节目My-Secret-Header(这是意料之中的)创建了大量的登录信息。

将自定义标头添加到客户端请求的最佳方法是什么,以便可以在 WAF 中创建规则?

标签: amazon-web-servicesamazon-s3aws-api-gatewayamazon-cloudfrontamazon-waf

解决方案


我想限制对 API 的访问,使其只能从客户端获得,并且当有人尝试直接访问 API 时它应该返回错误。

简短的回答是:没有办法做到这一点。无法判断请求是否来自浏览器中的 JavaScript、Postman 调用、用户在地址栏中键入 URL 等。

CloudFront 中的自定义标头不是添加到用户从提供的文件发出的 API 请求中的标头。它们是CloudFront 用于检索它所服务的静态源的标头。在源位于 S3 存储桶中的情况下,这些自定义标头位于 CloudFront 用于从您的 S3 存储桶中检索文件的请求中。

一旦用户拥有 CloudFront 提供的文件(HTML、CSS、JavaScript、资产等),CloudFront 就不再是流程的一部分。在前端进行的任何 API 调用都不会通过 CloudFront。

有一些非常弱的方法可以做你想做的事情,但所有这些方法都很容易绕过,并且在任何需要安全性时绝对不能使用。例如,您可以创建一个 API 密钥并将其硬编码到应用程序中,但它完全暴露给任何可以访问该页面的人。硬编码的访问密钥 ID 和秘密访问密钥也是如此。

最终,您需要一个身份验证系统,以某种方式确保允许用户进行他们正在进行的 API 调用。我不知道这是否适合您的用例,但 Amazon Cognito 是一项出色的服务,可以处理用户身份验证和联合。


推荐阅读