【问题标题】:How to limit AWS API Gateway access to specific CloudFront distribution or Route53 subdomain如何限制 AWS API Gateway 对特定 CloudFront 分配或 Route53 子域的访问
【发布时间】:2020-07-01 23:41:58
【问题描述】:

我有一个要限制访问的 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.

【问题讨论】:

    标签: amazon-web-services aws-api-gateway amazon-iam aws-resource-group


    【解决方案1】:

    "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 接受: */*

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

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

    【讨论】:

    • 谢谢,我会试试的
    【解决方案2】:

    问题是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"
    

    【讨论】:

      【解决方案3】:

      我在 AWS Route 53 中有一个指向 CloudFront 的子域设置 我的应用程序所在的分布。此应用程序向 API。

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

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

      如果是这样的话, 你需要阅读more about CORS

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-06-16
        • 2017-12-09
        • 1970-01-01
        • 2023-03-11
        • 1970-01-01
        • 1970-01-01
        • 2019-02-26
        • 1970-01-01
        相关资源
        最近更新 更多