【问题标题】:getting message: forbidden reply from AWS API gateway获取消息:来自 AWS API 网关的禁止回复
【发布时间】:2017-04-20 15:51:08
【问题描述】:

我正在尝试在 AWS 上创建一个 lambda 服务,并通过 API 网关从外部访问它,无需身份验证或限制。

为了方便起见,我现在将网关设置为 Mock。

在 API 的 Get 方法上,Authorization 设置为None,API Key 为not required

当我尝试这个时,我得到{"message":"Forbidden"} (如果我将它连接到实际的 lambda 服务,则显示相同的消息)。

关于如何使其可访问的任何建议?

【问题讨论】:

  • 部署前是否添加了get方法?
  • 我想知道您没有正确的调用 URL。
  • 我不能拒绝这个问题,但我想这样做。 “类似”的答案对社区没有帮助。由于 serverless.yml 文件中的缩进错误,我尝试了禁止消息。
  • 请选择正确答案旁边的复选标记,而不是在您的问题中添加[solved]。谢谢!
  • 如果您解释出了什么问题以及如何解决问题,将会很有用。

标签: amazon-web-services aws-api-gateway


【解决方案1】:

如果您将“需要 API 密钥”选项设置为 true,请检查以下内容。

  1. 您必须将“x-api-key”HTTP 标头参数传递给 API 网关。
  2. 必须创建 API 密钥。
  3. 另外,您需要在 API Gateway 控制台查看 API Key 的使用计划。

【讨论】:

  • 谢谢丹尼尔,你的第三步让我修正了我的错误。
  • 这对我有用,但它必须是 'X-Api-Key' 看起来大写很重要
  • 所有三个步骤都为我完成了。我已经创建了一个 API 密钥,但没有将它链接到使用计划或任何东西。非常感谢!
  • 您回答中的第 3 点经常被忽略。原来是我的问题。
  • @Marecky 和 ​​pixelwiz,我只是在处理一个类似的问题,为了增加 pixelwiz 的经验,我遇到了同样的问题。搜索后,我发现 AWS API Gateway 确实有一个“已知问题”,它确实会以“区分大小写”的方式处理标头。查看本页底部:docs.aws.amazon.com/apigateway/latest/developerguide/…
【解决方案2】:

在 API Gateway 仪表板上选择资源,单击操作并选择部署 API。在您第一次部署之前,您会得到的唯一回复是{"message":"Forbidden"}

【讨论】:

  • 我会补充一点,在您部署后确保将您的阶段名称添加到 URL:abcdefg.execute-api.us-east-2.amazonaws.com/STAGE_NAME/
【解决方案3】:

如果该方法的AuthorizationAPI KEY Required 都设置为true,那么请确保在发送请求时具有以下标头:

  1. Content-Type(如果 GET 调用通常是 application/x-www-form-urlencoded)
  2. 主机
  3. X-Amz-日期
  4. 授权
  5. x-api-key

我使用POSTMAN 进行 API 测试,它非常可靠,而且非常简单。

注意:如果您将API KEY REQUIRED 设置为 FALSE,请不要添加 x-api 密钥头。 如果您已将 AUTHORIZATION 设置为 FALSE,则不要添加 Authorization 标头。

【讨论】:

    【解决方案4】:

    我遇到了类似的问题,我遇到了以下问题:

    1. 自定义域(边缘优化)
    2. 多个阶段(开发、登台、产品)

    我也没有设置任何授权或限制以使事情变得简单。

    我能够通过为我的每个阶段(dev、staging、prod)添加基本路径映射来解决问题。

    【讨论】:

    • 我有相同的基本设置和多个 API。有趣的是,即使我的 API 只有一个 实际部署了,我仍然收到“禁止”,直到我为未部署的 API 设置基本路径映射。
    • 我在自定义域和多个阶段遇到了同样的问题,但我通过 CDK 和每个阶段的不同堆栈进行部署。即使我将所有堆栈部署在一起,我也会在我的某个阶段被禁止。有什么想法吗?
    【解决方案5】:

    如果您使用自定义域名并忘记选择目标暂存,您将收到Forbidden 消息。

    只需转到Custom Domain Names并单击您的域下的Edit,然后选择Base Path Mappings下的阶段。

    【讨论】:

    • 效果很好,并确保遵循@jneves 的回答并(重新)部署。设置映射后,它直到我重新部署从基本路径映射中选择的阶段才显示。
    • 总有一点缺失!谢谢
    • 这个隐藏的提示刚刚节省了我的工作时间,谢谢 :)
    • 这也是给我的。尽管他们在这里稍微更新了 GUI。现在正确的区域是进入自定义域名 > API 映射
    【解决方案6】:

    如果将 'API' key required 设置为 true,则需要将 api 密钥作为标头传递。

    API 密钥作为标头字段“x-api-key”传递。即使在标题中添加此字段后,也可能会出现此问题。在这种情况下,请验证以下几点

    • 您有使用计划吗?如果不需要创建一个。
    • 将您的 API 与使用计划相关联。为此添加一个阶段,它将链接您的 API。
    • 您有 API 密钥吗?如果不是,您需要创建一个 API 密钥并启用它。
    • 将与您的 API 链接的使用计划添加到此 API 密钥。为此添加使用计划。

    【讨论】:

      【解决方案7】:

      我从尝试访问 API Gateway 中的私有 API 的 nginx fargate 服务收到此错误。我需要像这样在我的 api 中的资源策略下添加一个策略

      {
          "Version": "2012-10-17",
          "Statement": [
              {
                  "Effect": "Allow",
                  "Principal": "*",
                  "Action": "execute-api:Invoke",
                  "Resource": "arn:aws:execute-api:us-east-1:<AccountID>:<RestApiID>/*",
                  "Condition": {
                      "StringEquals": {
                          "aws:sourceVpce": "<VPC Endpoint ID for execute-api>"
                      }
                  }
              }
          ]
      }
      

      【讨论】:

        【解决方案8】:

        当我们使用 Kong 作为我们的 api 网关时,我们在生产中遇到了这个问题。我们的请求在从 Postman 发起时通过了,但在通过 Code 发起时以 403 失败。 Kong 中的 Bot 插件已启用,仅允许基于用户代理标头值从浏览器或移动应用程序发起的请求。我们通过 Http 客户端发起的请求失败。一旦我们禁用了机器人插件,错误就不会发生。如果用户代理是 Apache-HttpClient/4.5.2 (Java/1.8.0_91),它现在允许请求。

        【讨论】:

          【解决方案9】:

          我可能为时已晚,但 API Gateway 给出“禁止”消息的原因之一是当您在 GET 操作的请求正文中传递数据时。要解决这个问题,要么让你的资源 POST,要么你不在请求正文中传递数据。

          【讨论】:

          • 正在使用 Insomnia 并将我的请求从 POST 更改为 GET。请求类型仍在 GraphQL Query - 返回 403 Forbidden 错误。将请求类型从 GraphQL Query 更改为 No Body 成功了!
          • 你救了我的命!
          • 嗯,非常感谢!
          【解决方案10】:

          这可能远非显而易见,但在使用 AWS API Gateway 时看到“禁止”错误的另一个原因可能是调用了与任何已部署 API 方法不对应的错误 URL。如果您实际上点击了错误的 URL(例如,而不是在 users 之前调用 dev 阶段而不是在 users 之前调用 https://9999xx9x99.execute-api.us-east-1.amazonaws.com/users(无阶段),则可能会发生这种情况。您希望得到 404,但您会得到 403。

          顺便说一句:在您对https://9999xx9x99.execute-api.us-east-1.amazonaws.com/dev/users 调用https://9999xx9x99.execute-api.us-east-1.amazonaws.com/user(此处注意单数名词形式)进行部署后,您也会得到... 403,但带有“缺少身份验证令牌”消息!

          【讨论】:

          • 这可能远非显而易见,但在使用 AWS API Gateway 时看到“Forbidden”错误的另一个原因可能是调用了与任何已部署 API 方法不对应的错误 URL。如果您实际上点击了错误的 URL(例如,而不是调用 9999xx9x99.execute-api.us-east-1.amazonaws.com/dev/users(注意用户之前的开发阶段)您调用了 9999xx9x99.execute-api.us-east-1.amazonaws.com/users(无阶段),则可能会发生这种情况。您希望得到 404,但您会得到 403 . ruby​​ rack aws lambda api gateway端点如何解决这个问题?
          • @AnkitaDhandha,提出一个新问题。
          【解决方案11】:

          您需要在舞台上部署您的 api 并使用舞台 url 转到 Resources,单击 Actions 并选择 Deploy API

          现在如果你遇到错误

          {“消息”:“禁止”}。

          请检查以下步骤

          1) 如果您启用 api 密钥复制并在邮递员中传递您的密钥

          2) 现在你仍然得到同样的错误意味着你需要创建使用计划

          3) 设置限制并为您的 api 分配计划

          【讨论】:

          • 看不到图片
          【解决方案12】:

          本地防火墙/防病毒或 NGIPS (Cisco Bluecoat)。后者是我的情况,我什至不会从我的 API 获取 CloudWatch 中的日志。它允许我的顶级域托管网站,但用 403 阻止了 api 子域,浏览器的网络开发工具选项卡中没有正文。

          【讨论】:

            【解决方案13】:

            当我们在 API Gateway 中收到 {message: 禁止} 时,需要做一些事情:

            是否启用了 CORS?

            1. 检查是否在 API 中启用了 CORS(首先,允许来源 '*',以确保我们可以安全地测试)
            2. 部署 API 以确保所有设置都符合预期

            API 密钥已启用?

            1. 检查我们是否在 API 网关中启用了 API 密钥
            2. 检查是否配置了 API 密钥。
            3. 检查您的 API 密钥是否已分配给正确的使用计划并添加 API 阶段,如果没有 API 阶段,您将始终收到 {message: 禁止}

            如果您仍然遇到问题,请告诉我,以便我或我们的一位云专家 @levarne 可以提供帮助。

            【讨论】:

              【解决方案14】:

              我在 EndpointConfiguration 设置为 PRIVATE 的 API 上获得了{"message":"Forbidden"},并在 Vpc 的私有子网中为其创建了一个 VpcEndpoint(这是一个服务间 API)

              我得到{"message":"Forbidden"} 的原因是我认为我应该使用 VpcEndpoint 的 URL 之一。要使用的 URL 仍然是与阶段关联的 URL(在 ApiGateway 控制台中)。它是:

              https://${RestApiId}.execute-api.${Region}.amazonaws.com/${StageName}

              【讨论】:

                【解决方案15】:

                我可能已经找到了解决此问题的方法。 我现在在 MacOS 上遇到了同样的问题。 我尝试刷新我的 DNS,然后成功了!

                在终端试试这个:

                Mac OS X Yosemite 及更高版本

                sudo killall -HUP mDNSResponder
                

                Mac OS X Yosemite v10.10 到 v10.10.3

                sudo discoveryutil mdnsflushcache
                

                Mac OS X Mavericks、Mountain Lion 和 Lion

                sudo killall -HUP mDNSResponder
                

                Mac OS X 雪豹

                sudo dscacheutil -flushcache
                

                【讨论】:

                  【解决方案16】:

                  把我的经验也放在这里。我尝试了上面所有这些方法,结果发现使用通配符放置域解决了我的 {"message":"Forbidden"} 问题:*.mydomain.com

                  【讨论】:

                    【解决方案17】:

                    我所经历的唯一其他原因,我没有看到这里提到的字面意思是你试图在发布后太快地访问 API。我点击发布并看到“您的 API 可访问”域名,然后立即将其复制并粘贴到 Postman 中进行检查。

                    我收到了禁止消息。什么都不改变。检查所有设置以确保我没有做任何事情 - 一切都是正确的。有点把我的头发扯掉了。

                    几分钟后返回尝试,因为我很确定我做的一切都是正确的 - 它有效。

                    DNS 人。无论互联网有多快——它都不是即时的 :)

                    【讨论】:

                      【解决方案18】:

                      就我在 Swagger Editor 中遇到的类似案例做一个说明:

                      • 我从 API Gateway 导出 OpenAPI 3.0 YAML → Stages → 选择“Prod” → 选择“Export”选项卡 → 将单选按钮切换到“OpenAPI 3” → “Export as OpenAPI 3 + API Gateway Extensions”
                      • 将收到的YAML粘贴到https://editor.swagger.io/
                      • 执行一个简单的 GET 方法。
                      • 它返回 403 Forbidden{"message":"Forbidden"} 正文。

                      来自 Swagger 编辑器的curl 命令如下所示:

                      curl -X GET "https://xxx52xxxx9.execute-api.eu-central-1.amazonaws.com//Prod/users" -H "accept: application/json"

                      (注意Prod之前的双//)。

                      没有// 的相同curl 命令通过命令行工作!

                      有效的技巧是替换 API 网关生成的 server 结构:

                      servers:
                        - url: "https://xxx52xxxx9.execute-api.eu-central-1.amazonaws.com/{basePath}"
                          variables:
                            basePath:
                              default: "/Prod"
                      

                      完整的url 没有variables

                      servers:
                        - url: "https://xxx52xxxx9.execute-api.eu-central-1.amazonaws.com/Prod"
                      

                      值得注意的是,从 default: "/Prod" 中删除前导斜杠并没有帮助。

                      【讨论】:

                        【解决方案19】:

                        在我的情况下,api 密钥未启用。 确保 API 设置为已启用。

                        【讨论】:

                          【解决方案20】:

                          正如@gary69 和@Adriaan Pelzer 提到的

                          https://stackoverflow.com/a/52727654/809043

                          https://stackoverflow.com/a/55136675/809043

                          你可以在请求一个 私有 API。

                          因此,如果您有一个设置,其中所有流量都应通过 API 端点,而不是将流量定向到 API 网关,则可以使用以下参数。

                          APIGatewayVPCEndpoint:
                            Type: 'AWS::EC2::VPCEndpoint'
                            Properties:
                              PolicyDocument: '{
                                  "Version":"2012-10-17",
                                  "Statement":[{
                                    "Effect":"Allow",
                                    "Principal": "*",
                                    "Action":["execute-api:Invoke"],
                                    "Resource":["arn:aws:execute-api:eu-north-1:000000000000:*/*"]
                                  }]
                                }'
                            ...
                            VpcEndpointType: Interface
                            PrivateDnsEnabled: true
                          

                          如果启用 PrivateDnsEnabled,则 API 网关中的端点需要为私有类型,并且需要添加策略。

                            ApiGatewayRest:
                              Type: AWS::ApiGateway::RestApi
                              Properties:
                                Description: A mocked API
                                Name: Mocked API
                                EndpointConfiguration:
                                  Types:
                                    - PRIVATE
                                Policy: '{
                                  "Version": "2012-10-17",
                                  "Statement": [{
                                    "Effect": "Allow",
                                    "Principal": "*",
                                    "Action": "execute-api:Invoke",
                                    "Resource": "arn:aws:execute-api:eu-north-1:000000000000:*/*/*/*"
                                  }]
                                }'
                          

                          这个论坛帖子帮我弄清楚了一些细节

                          https://forums.aws.amazon.com/thread.jspa?threadID=286760

                          【讨论】:

                            【解决方案21】:

                            我遇到了类似的问题。原来我在证书管理器中的证书不是在北弗吉尼亚地区 (us-east-1) 创建的,因此我无法将自定义域标记为边缘优化。我不得不选择区域性。

                            当我使用 N. Virginia 区域重新导入证书并再次创建自定义域时,但这次使用边缘优化的端点配置,它可以完美运行。

                            【讨论】:

                              【解决方案22】:

                              就我而言,这是因为我使用了

                              Managed-AllViewer

                              源请求策略。切换到

                              Managed-UserAgentRefererHeaders

                              解决了问题。

                              我的客户发送了一个 Accept-Encoding 标头,CloudFront 不喜欢它。您可以通过创建“白名单”类型的自定义源请求策略来验证这一点,尽管可以从列表中选择 Accept-Encoding,但在创建策略时会收到错误消息:"The parameter Headers contains Accept-Encoding that is not allowed."

                              很遗憾,我没有找到相关文档。也不知道为什么不允许使用这种不起眼的标题。

                              【讨论】:

                              • 这解决了我的问题。可以通过 API Gateway 上的调用运行所有方法,但是当我在 Postman 中运行相同的方法进行测试时,所有 POST 方法都得到 403。
                              【解决方案23】:

                              当我们尝试使用不正确的策略访问私有 API 端点并且没有在调用请求中传递“HOST”标头时,通常会出现这种情况。 假设我有一个 API 部署为具有以下资源策略的私有端点。

                              {
                              "Version": "2012-10-17",
                              "Statement": [
                                  {
                                      "Effect": "Allow",
                                      "Principal": "*",
                                      "Action": "execute-api:Invoke",
                                      "Resource": "arn:aws:execute-api:us-west-2:12345678:2ucqasdfasdfryc/*"
                                  },
                                  {
                                      "Effect": "Deny",
                                      "Principal": "*",
                                      "Action": "execute-api:Invoke",
                                      "Resource": "arn:aws:execute-api:us-west-2:12345678:2dgaucqt6dfgdyc/*",
                                      "Condition": {
                                          "StringNotEquals": {
                                              "aws:SourceVpce": "vpce-87878kjlkj8787k"
                                          }
                                      }
                                  }
                              ]
                              }
                              

                              在禁用私有 DNS 主机名时访问私有 API 端点。

                              curl -v -H 'Host: 01234567ab.execute-api.us-west-2.amazonaws.com' https://vpce-01234567abcdef012-01234567.execute-api.us-east-1.vpce.amazonaws.com/test/pets
                              
                                                        
                              

                              [或] 使用 API ID 而不是 Host 标头。

                              curl -v -H 'x-apigw-api-id: 01234567' https://vpce-01234567abcdef012-01234567.execute-api.us-east-1.vpce.amazonaws.com/test/pets
                              

                              【讨论】:

                                【解决方案24】:

                                一周前我也面临同样的问题,并花了一些时间来确定问题。我们的 api 网关端点已配置为仅通过公共网络工作,并且我们有一个 WAF 和资源策略来过滤对端点的传入请求。我能够从不同的 vpc 而不是特定的 vpc 访问端点。我收到了 Forbidden 错误。

                                最后,发现我尝试使用的 vpc 具有启用私有 DNS 的执行 api 服务的 VPC 端点。 API Gateway 端点正在解析为 VPC 内的私有 IP。

                                有两种方法可以解决它。一,我们可以禁用私有 DNS,这就是我所做的。更改后它开始工作得很好。但我们必须确保它不会影响正在使用 vpc 端点的其他人。

                                第二,我们可以使用自定义域名,我们可以使用它从 vpc 调用。

                                【讨论】:

                                  【解决方案25】:

                                  我今天收到此错误,因为签名标头中的 aws_host 不正确(使用 Boto3 和 AWSRequestAuth)。

                                  在重构时,我开始循环处理多个请求,但这个引入的请求位于不同的 API 上,需要不同的 aws_host。

                                  auth = AWSRequestsAuth(aws_access_key=credentials.access_key,
                                                         aws_secret_access_key=credentials.secret_key,
                                                         aws_token=credentials.token,
                                                         aws_host=f'api.{env}.XXX.dk',
                                                         aws_region=region,
                                                         aws_service='execute-api')
                                  

                                  【讨论】:

                                    【解决方案26】:

                                    我的问题是我连接到我办公室的 VPN,该 VPN 路由到我公司在 AWS 中的 VPC。我的公司设置了私有 DNS,导致对公共端点的请求被路由到属于 API 网关的 VPC 接口端点的私有 IP 地址。

                                    This article 解释了一切。

                                    有两种解决方案:

                                    1. 点击调用 URL 时关闭 VPN。
                                    2. 使用 API Gateway 自定义域。

                                    我最终使用了解决方案 1,因为我需要在 API 网关前面设置一个云端,并且我要使用的自定义域已经设置为 Edge 类型以及与之关联的其他 api 网关。

                                    作为其他参考,不能将边缘类型自定义域设置为另一个云端的来源,因为它使用 CloudFront 来加速所有地理位置的连接。详情请见this AWS support article

                                    【讨论】:

                                      猜你喜欢
                                      • 2021-12-23
                                      • 2018-11-09
                                      • 2017-12-23
                                      • 1970-01-01
                                      • 1970-01-01
                                      • 1970-01-01
                                      • 2017-11-28
                                      • 2016-12-08
                                      • 2016-09-05
                                      相关资源
                                      最近更新 更多