Amazon S3请求签名不匹配及批量列取对象问题咨询
一、签名不匹配(403)问题排查与解决
当prefix包含斜杠或添加marker参数时出现签名不匹配,核心原因是SigV4签名要求canonical_query_string与实际请求URL的查询参数完全一致,包括编码、参数顺序、格式细节,以下是具体修复步骤:
严格匹配参数编码与格式:
S3对prefix中的斜杠/处理特殊:如果请求URL中直接写prefix=202302/test,则canonical_query_string必须保持prefix=202302/test;如果URL中转义为prefix=202302%2Ftest,则canonical_query_string也必须使用prefix=202302%2Ftest,两者不能混用。按ASCII升序排列查询参数:
SigV4要求canonical_query_string中的参数必须按参数名的ASCII码升序排列。例如同时使用prefix和marker时,必须写成marker=test&prefix=202302/test,不能颠倒顺序,否则签名计算会出错。验证空请求的SHA256值:
因为是GET请求,请求体为空,x-amz-content-sha256必须设置为空字符串的SHA256哈希值:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855,如果使用了错误的哈希值会直接导致403。核对Authorization头的签名源:
重新检查生成authorization_header时使用的canonical_query_string是否与实际请求URL中的查询参数完全一致,包括所有参数、编码、顺序,任何细微差异都会导致签名不匹配。
二、列取超过1000个S3对象的方案
S3默认单次返回最多1000个对象,需通过分页参数实现批量列取,分两种API场景处理:
1. 使用List Objects V1 API(传统方式)
- 首次请求不带
marker,如果返回结果中IsTruncated为true,说明还有更多对象; - 下一次请求将返回结果中的
NextMarker值作为marker参数传入,重复请求直到IsTruncated为false。
2. 使用List Objects V2 API(推荐)
- 首次请求添加
list-type=2参数启用V2 API; - 如果返回结果中
IsTruncated为true,使用返回的NextContinuationToken作为continuation-token参数传入下一次请求,直到IsTruncated为false。
修正后的示例curl脚本
假设使用V1 API,同时带prefix和marker的正确请求(确保canonical_query_string与URL参数一致):
# 构造正确的canonical_query_string(参数按ASCII升序排列) canonical_query_string="marker=test&prefix=202302/test" current_date_iso8601=$(date -u +"%Y%m%dT%H%M%SZ") # 空请求的SHA256哈希 payload_hash="e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" curl -X GET -v --proxy "proxy_url" "https://s3endpoint?$canonical_query_string" \ -H "Authorization: $authorization_header" \ -H "Content-Type: application/x-www-form-urlencoded" \ -H "x-amz-content-sha256: $payload_hash" \ -H "x-amz-date: $current_date_iso8601"
内容的提问来源于stack exchange,提问作者milky_way

