AWS API Gateway反向代理SQS出现AccessDenied报错排查
问题描述
尝试配置AWS API Gateway作为反向代理对接AWS SQS,实现向API Gateway发送REST请求后,由网关直接转发请求至SQS REST API并返回对应响应。
向网关发起请求时,立刻返回如下AccessDenied报错:
<?xml version="1.0"?> <ErrorResponse xmlns="http://queue.amazonaws.com/doc/2012-11-05/"> <Error> <Type>Sender</Type> <Code>AccessDenied</Code> <Message>Access to the resource https://sqs.us-east-1.amazonaws.com/ is denied.</Message> <Detail/> </Error> <RequestId>51c903b2-4da3-5d5e-a3b8-589ee72167de</RequestId> </ErrorResponse>
将请求URL直接切换为SQS端点(https://sqs.us-east-1.amazonaws.com)时,请求可正常执行,需排查配置遗漏项。
根因分析
该报错由透传客户端SigV4签名时,API Gateway修改了签名强绑定的请求字段,导致SQS侧签名校验失败导致:
- AWS SigV4签名会将请求
Host头、请求路径、请求方法、指定参与签名的头/查询参数/请求体作为签名因子,本次请求的签名是针对SQS官方端点sqs.us-east-1.amazonaws.com、根路径/生成的 - API Gateway的HTTP_PROXY集成默认会将转发请求的
Host头替换为API Gateway自身域名,若配置了路径重写规则,转发到SQS的实际路径也会和签名时的路径不一致 - SQS收到请求后校验签名,发现关键字段和签名内容不匹配,直接返回AccessDenied。直连SQS时无中间层修改请求字段,因此签名校验通过、请求正常。
解决方案
根据使用场景二选一即可:
方案1:保留客户端签名透传逻辑
需修改API Gateway集成配置,保证签名相关字段原样转发:
- 在集成请求的HTTP头配置中,手动指定转发给SQS的
Host头值为sqs.us-east-1.amazonaws.com,覆盖API Gateway默认替换Host的逻辑 - 配置路径重写规则:将API Gateway上
/sqs路径的请求重写为根路径/后转发,保证转发路径和签名时使用的路径完全一致 - 关闭API Gateway对请求头、请求体的自动改写逻辑,所有参与SigV4签名的字段不做修改直接透传
方案2:API Gateway统一承担签名逻辑(推荐)
该方案无需客户端感知SQS签名规则,耦合度更低:
- 移除客户端透传的
Authorization、X-Amz-Date、X-Amz-Security-Token等SigV4签名相关头 - 为API Gateway配置专用IAM执行角色,给角色授予对应SQS操作的权限(如
sqs:ReceiveMessage、sqs:SendMessage等业务需要的权限) - 在集成配置中开启AWS SigV4签名,指定区域为
us-east-1、服务为sqs,由API Gateway通过执行角色自动为转发到SQS的请求生成合法签名,客户端只需按照API Gateway自定义的鉴权规则请求即可。
复现请求示例
curl --request POST 'https://my-api-gateway.com/sqs' \ --header 'X-Amz-Date: <date>' \ --header 'X-Amz-Security-Token: <token>' \ --header 'Authorization: <auth>' \ --header 'Amz-Sdk-Invocation-Id: <invocation>' \ --header 'Amz-Sdk-Request: attempt=1; max=10' \ --header 'User-Agent: aws-sdk-go-v2/1.16.5 os/macos lang/go/1.18.3 md/GOOS/darwin md/GOARCH/arm64 api/sqs/1.18.6' \ --header 'Content-Length: 206' \ --data-urlencode 'Action=ReceiveMessage' \ --data-urlencode 'MaxNumberOfMessages=10' \ --data-urlencode 'QueueUrl=<my-queue-url>' \ --data-urlencode 'Version=2012-11-05' \ --data-urlencode 'WaitTimeSeconds=20'
相关配置截图
内容的提问来源于stack exchange,提问作者aarbor
相关产品推荐
相关产品推荐

