9

我有一个要限制访问的 API Gateway api 设置。我在 AWS Route 53 中有一个子域设置,它指向我的应用程序所在的 CloudFront 分配。此应用程序向 API 发出 POST 请求。

我已经考虑根据示例“AWS API 白名单”为我的 api 添加资源策略,但我似乎无法正确获取语法,我经常遇到错误。

我还尝试创建一个 IAM 用户并使用 AWS_IAM auth 锁定 API,但随后我需要创建一个签名请求,这似乎是很多工作,通过资源策略应该会容易得多?

这是我尝试附加到我的 API 的资源策略的示例:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity {{CloudFrontID}}"
            },
            "Action": "execute-api:Invoke",
            "Resource": [
                "execute-api:/*/*/*"
            ]
        }
    ]
}

这将返回以下错误: Invalid policy document. Please check the policy syntax and ensure that Principals are valid.

4

3 回答 3

3

“AWS”:“arn:aws:iam::cloudfront:user/CloudFront 源访问身份 {{CloudFrontID}}”

这个概念的问题在于这是一个公共 HTTP 请求。除非它是一个签名请求,否则 AWS 不会知道任何 IAM 或 ARN 资源,它只知道它有一个标准的 HTTP 请求。如果您使用 curl -v 命令发出请求,您将看到请求参数如下所示:

    得到
    /test/mappedcokerheaders
    HTTP/2
    主机:APIID.execute-api.REGION.amazonaws.com
    用户代理:curl/7.61.1
    接受: */*

您可以过滤用户代理,因为我确实看到了此处定义的条件。

我将通过在响应标头中捕获 api gw 请求 ID 并在 API 网关访问日志中查找这些值,来检查来自 cloudfront 的请求中的所有值与来自 curl 的请求直接到 API 的所有值。不过,您必须启用访问日志,并定义要记录的参数,您可以在此处查看如何操作。

于 2019-09-27T17:59:59.337 回答
3

问题是 OAI 不能在CustomOrigin中使用。如果您不转发User-Agent到 API Gateway CustomOrigin,那么最简单的方法是在 API Gateway 中添加一个资源策略,它只允许aws:UserAgent: "Amazon CloudFront".

小心: User-Agent容易被欺骗。这种方法旨在仅防止“正常访问”,例如网络上的随机机器人试图抓取您的网站。

标题User-Agent保证为Amazon CloudFront. 请参阅Request and Response Behavior for Custom Origins中的引用。

未将 CloudFront 配置为基于标头值进行缓存时的行为:CloudFront将此标头字段的值替换Amazon CloudFront为。如果您希望 CloudFront 根据用户使用的设备缓存您的内容,请参阅根据设备类型配置缓存。

完整资源策略如下所示:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws:execute-api:us-west-2:123456789012:abcdefghij/*/*/*",
            "Condition": {
                "StringEquals": {
                    "aws:UserAgent": "Amazon CloudFront"
                }
            }
        }
    ]
}

以下是如何配置它serverless.yml

provider:
  resourcePolicy:
    - Effect: Allow
      Principal: "*"
      Action: execute-api:Invoke
      Resource:
        - execute-api:/*/*/*
      Condition:
        StringEquals:
          aws:UserAgent: "Amazon CloudFront"
于 2020-07-01T15:33:29.960 回答
1

我在 AWS Route 53 中有一个子域设置,它指向我的应用程序所在的 CloudFront 分配。此应用程序向 API 发出 POST 请求。

我的理解是你有一个可以从网络浏览器调用的公共服务(https://your-service.com

您希望服务仅在客户端浏览器位于https://your-site.com时响应。例如,当浏览器位于https://another-site.com上时,该服务将不会响应

如果是这种情况,您将需要阅读有关 CORS的更多信息

但是,这不会阻止随机的人/网络客户端直接将您的服务调用到 https://your-service.com。为了保护服务免受这种影响,您需要适当的身份验证系统

于 2019-09-27T03:42:12.630 回答