getting message: forbidden reply from AWS API gateway

I am trying to create a lambda service on AWS and have it accessed from outside via the API gateway with no authentication or restriction required.

To make things easy I set the gateway for now to be a Mock.

On the Get method of the API, the Authorization is set to None and the API Key is not required.

When I try this, I get {"message":"Forbidden"} (same message if I connect it to the actual lambda service).

Any advice on how to make it accessible?

146733 次浏览

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

  1. 您必须将‘ x-API-key’HTTP Header 参数传递给 API 网关。
  2. 必须创建 API 密钥。
  3. 此外,您还需要检查 API 网关控制台上 API 密钥的使用计划。

在 API 网关仪表板上选择参考资料,单击 Actions 并选择 DeployAPI。在第一次部署之前,您将得到的唯一响应是 {"message":"Forbidden"}

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

  1. Content-Type (通常是 application/x-www-form-urlencode,如果 GET 调用的话)
  2. 主持人
  3. X-Amz-Date
  4. 授权
  5. X-api-key

我使用 POSTMAN的 API 测试,这是相当可靠的,然后它是美丽的直接。

注意: 如果您将 API KEY REQUIRED设置为 FALSE,则不要添加 x-api 键头。 如果您将 AUTHORIZATION设置为 FALSE,则不要添加授权标头。

I had a similar problem, and I had the following:

  1. 自定义域(边缘优化)
  2. 多个阶段(dev、 stage、 prod)

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

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

如果您使用自定义域名并忘记选择目的地登台,您将收到 Forbidden消息。

Simply go to Custom Domain Names and click Edit under your domain, and then select the stage under Base Path Mappings.

如果将“ API”键设置为 true,则需要将 API 键作为头传递。

API 键作为头字段‘ x-API-Key’传递。即使在 Header 中添加了此字段,也可能出现此问题。在这种情况下,请验证以下几点

  • 你有一个使用计划? 如果不需要创建一个。
  • Link you API with Usage Plan. For that add a stage, it will link your API.
  • 你有 API 密钥吗? 如果没有,你需要创建一个 API 密钥并启用它。
  • 将与您的 API 链接的使用计划添加到此 API 键中。

我从一个试图访问 API 网关中的私有 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>"
}
}
}
]
}

当我们使用 Kong 作为我们的 api 网关时,我们在生产中遇到了这个问题。我们的请求通过时,从邮递员发起,但失败与403时,通过代码发起。启用了 Kong 中的 Bot 插件,它只允许基于用户代理头值从 Browser 或 Mobile App 发起请求。我们通过 Http 客户端发起的请求失败。一旦我们禁用了 bot 插件,那么错误就不会发生。现在,如果用户代理是 Apache-HttpClient/4.5.2(Java/1.8.0 _ 91) ,它就允许请求。

我可能为时已晚,但 API 网关会给出“禁止”消息的原因之一是,当您在 GET 操作的请求体中传递数据时。若要解决此问题,请使用资源 POST 或不在请求体中传递数据。

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

BTW: after you make a deployement to https://9999xx9x99.execute-api.us-east-1.amazonaws.com/dev/users calling https://9999xx9x99.execute-api.us-east-1.amazonaws.com/user (note singular noun form here) you'll get… 403 as well, but with "Missing Authentication Token" message!

您需要在 stage 上部署您的 API 并使用 stage URL,然后转到参考资料,单击 Actions 并选择 DeployAPI

现在,如果你正在得到错误

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

请检查以下步骤

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

enter image description here

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

enter image description here

3) set limit and assign plan to your api

enter image description here

本地防火墙/防毒软件或 NGIPS (西斯科蓝外套)。后者是我的情况,我甚至不能从 API 获得 CloudWatch 中的日志。它允许我的顶级域托管网站,但阻塞了403的 api子域,没有体在浏览器的网络开发工具选项卡。

当我们在 API 网关中接收到{ message:  禁止}時,有一些事情要做:

CORS 启动了吗?

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

启用 API 密钥?

  1. 检查我们是否在 API 网关中启用了 API 密钥
  2. 检查是否配置了 API 密钥。
  3. 检查您的 API 密钥是否分配到正确的使用计划,并添加一个 API Stage,如果没有 API Stage,您将总是会收到一个{ message: ban }

如果您仍然面临问题,请让我知道,以便我或我们的云大师之一@levarne 可以提供帮助。

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

The reason I got {"message":"Forbidden"} was that I was under the impression I should use one of the VpcEndpoint's urls. The URL to use is still the one associated with the stage (in ApiGateway console). It is:

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

我可能找到了解决这个问题的办法。 I had the same issue right now on MacOS. I tried to 把我的域名冲掉 and then it worked!

在终端机试试这个:

Mac OS X Yosemite and later

sudo killall -HUP mDNSResponder

Mac OS X Yosemite v10.10至 v10.10.3

sudo discoveryutil mdnsflushcache

Mac OS X Mavericks,Mountain Lion and Lion

sudo killall -HUP mDNSResponder

Mac OS X Snow Leopard

sudo dscacheutil -flushcache

把我的经验也放在这里。我尝试了上面所有的方法,结果发现用通配符放置域解决了我的 {“信息”: “禁止”}问题: * 。Mydomain.com

Custom domain

我在这里没有提到的另一个原因是,您在发布之后试图快速访问 API。我点击发布,看到“你的 API 是可达的”域名,并立即复制粘贴到邮递员检查它。

我明白你的意思了。什么都不要改变。检查所有设置,以确保我没有做任何事情-一切都是正确的。有点抓狂。

Return a few minutes later to try because I'm quite sure I'm doing it all correct - it works.

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

关于我在《时尚编辑》中遇到的类似案例,我想说明一下:

  • I exported the OpenAPI 3.0 YAML from API Gateway → Stages → select "Prod" → select "Export" tab → switch radiobutton to "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之前的双 //)。

And the same curl command without // worked via the command line!

有效的方法是替换 API 网关生成的返回的 server结构:

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

With the full url without variables:

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

Notably, removing the leading slash from default: "/Prod" didn't help.

在我的例子中,没有启用 api 密钥。 确保将 API 设置为“已启用”。 enter image description here

就像@gary69和@Adrian Pelzer 提到的

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

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

当请求一个 Private 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

如果启用 PrivateDnsEnable,则 API 网关中的端点需要为 Type Private,并且需要添加策略。

  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

我也有过类似的问题。结果证书管理器中的证书不是在北弗吉尼亚州(us-east-1)创建的,因此我不能将自定义域标记为边缘优化的。我不得不选择区域。

当我使用 N. Virginia 地区重新导入证书并再次创建自定义域时,但这次使用了 Edge 优化的端点配置,它完美地工作了。

对我来说,这是因为我使用了

Managed-AllViewer 管理-AllViewer

原产地要求政策。切换到

管理的 UserAgentRefererHeader

解决了问题。

My client sent an Accept-Encoding header, which CloudFront did not like. You can verify this by creating a custom origin request policy of type "Whitelist", and although Accept-Encoding is selectable from the list, you receive an error when creating the policy: "The parameter Headers contains Accept-Encoding that is not allowed."

遗憾的是,我没有找到相关文件。也不知道为什么这样一个不起眼的标题是不允许的。

This usually comes when we try to access the Private API endpoint with incorrect policy & without passing the 'HOST' header in the invoke request. 假设我有一个 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"
}
}
}
]
}

禁用 Private-DNS-hostname 时访问 Private 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


                          

[ OR ] 使用 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

I was also facing the same issue a week back and spent sometime to identify the issue. Our api gateway endpoint has been configured to work only through public network and we have a WAF & resource policy to filter the incoming requests to the endpoint. I was able to access the endpoint from a different vpc and not from a particular vpc. I was getting Forbidden error.

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

有两种方法可以解决这个问题。第一,我们可以禁用私人域名系统,我就是这么做的。在改变之后,它开始工作得非常好。但是我们必须确保它不会影响使用 vpc 端点的其他用户。

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

今天我收到了这个错误,因为签名头中的 aws _ host 不正确(使用 Boto3和 AWSRequestAuth)。

在重构时,我开始遍历多个请求,但是这个引入的请求位于需要不同 awshost 的不同 API 上。

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')

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

这篇文章 解释了这一切。

有两种解决办法:

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

我最终使用了解决方案1,因为我需要在 API 网关前面设置一个 Cloudfront,并且我想要使用的自定义域已经被设置为 Edge 类型,其他与之相关联的 API 网关也是如此。

作为额外的参考,Edge 类型的自定义域不能设置为另一个 CloudFront 的原点,因为它使用 CloudFront 来加速跨所有地理位置的连接。有关详细信息,请参阅 这篇 AWS 支持文章

添加到要查看的选项中:

“为什么在从 VPC 连接到 API 网关 API 时会出现 HTTP403禁止错误?”

If you have "private dns" enabled, and you use a VPCEndpoint, you might very well run into this issue. See: https://aws.amazon.com/premiumsupport/knowledge-center/api-gateway-vpc-connections/

在我的例子中,我在同一个帐户中有两个 API 网关:

  • 一个面向 Lambda 函数的公共 HTTP API 网关,
  • a private REST API Gateway fronting a lambda function (with a VPCEndpoint so that my ECS/Fargate containers could talk to the private API)

问题在于,一旦我设置了私有 API + VPCE ndpoint,它就开始从 WITHIN AWS 吸取所有流量到 API 网关(所以,不管是对我的公共 API 网关还是对我的私有 API 网关)。这破坏了 PUBLIC HTTP API。

我敲了一会儿我的头,因为,从我的笔记本电脑,我可以到达公共 API 网关,但不从我的船坞容器内的 AWS Fargate!

The possible solutions are:

  • 选项1: 添加一个 Route53到公共 API,如果您需要从您的 docker 容器调用它(这样,您的容器发出一个出站“ Internet 请求”并返回到公共网关[ ~ from out ])
  • 选项2: 对于公共 API,我最终选择了一个更简单的选项: 我去掉了公共 API,而是通过应用程序负载均衡器公开了我的 Lambda 函数: 只需要配置 TargetGroup 以指向 Lambda。

I now have:

  • My Private REST API Gateway (和 VPCEndpoint) ,它面向我的 Docker 容器的 Lambda 函数(在私有子网中运行的 AWS/Fargate)
  • 我的公开可用的 ALB 到达 Lambda 函数(不再使用 HTTP API 网关)。

对我来说,问题在于我在 API 设置中将 API Key Source设置为 AUTHORIZER,但是没有定义任何授权程序。

API 密钥来源

(这是由于我重用了设置它的 CDK 构造

    let restApiConfig: RestApiProps = {
restApiName: apiName,
apiKeySourceType: ApiKeySourceType.AUTHORIZER,   // <-- Should be HEADER
deployOptions: {
stageName: deployEnv,
...

)

Don't forget to redeploy the API if manually applying the change.

我也面临同样的问题 我可以通过在 URL 末尾添加一个“/”来解决这个问题

https://xxx52xxxx9.execute-api.eu-central-1.amazonaws.com/dev/hello

给出了错误 {"message":"Forbidden"}

但是 https://xxx52xxxx9.execute-api.eu-central-1.amazonaws.com/dev/hello/

给出了所需的输出

最初的问题是关于将 API 键设置为“不需要”。我遵循了答案中列出的几个步骤,但是我忘记做的主要事情是,因为我不熟悉 API 网关,我必须在将 API 键设置为“不需要”之后重新部署 API。

enter image description here

获得403的原因有很多,其中一个就是 这个问题

总结根本原因:

当在 VPC 端点上启用私有 DNS 时,API 的调用 URL 被私有 DNS 名称 * . execute-API.us-east-1.amazonaws.com 覆盖,其中 * 是 API ID 的占位符。当从 VPC 内部为公共 API 解析 DNS 查询时,解析后的 DNS 指向相关 VPC 端点的私有 IP,而不是公共 API 的公共 IP。API 调用然后通过 VPC 端点路由到公共 API,而不是通过 Internet 路由。因为 VPC 端点只能将流量路由到私有 API,所以结果是 HTTP403错误。

如果您在具有 API 网关 VPC 端点的 VPC 中运行 lambda,那么您将得到403。您可以在没有 VPC 的情况下运行 lambda 函数