AWS V4 身份验证要求您知道存储桶的区域,以便您可以正确签署请求。否则:
HTTP/1.1 400 Bad Request
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>AuthorizationHeaderMalformed</Code>
<Message>The authorization header is malformed; the region 'us-east-1' is wrong; expecting 'us-west-2'</Message>
<Region>us-west-2</Region>
<RequestId>xxxx</RequestId>
<HostId>xxxx</HostId>
</Error>
V2 签名不是特定于区域的,因此以前有一种简单的方法可以使用 V2 请求来了解存储桶的区域:
http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETlocation.html
但是,V4 似乎有一个 catch-22,因为您必须先知道存储桶的区域,然后才能进行调用以发现存储桶的区域。
那么,第一个解决方案是捕获错误响应中返回的<Region>,并使用该区域对存储桶的未来请求进行签名。显然,您希望缓存这些信息,因为不这样做会降低性能并增加成本。
或者,有一种方法可以仅使用以下 URL 格式向美国标准区域 (us-east-1) 询问任何区域中任何存储桶的位置:
https://s3.amazonaws.com/bucket-name?location
使用 us-east-1 区域签署此请求,无论存储桶在哪里,您都会收到响应。请注意,如果存储桶位于 us-east-1(美国标准)中,则 LocationConstraint 将返回为空。
<?xml version="1.0" encoding="UTF-8"?>
<LocationConstraint xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
us-west-2
</LocationConstraint>
您不能使用此 URL 构造来实际列出其他区域中的存储桶对象,因为 https://s3.amazonaws.com/ 始终将您的请求路由到 US-Standard (us-east-1),但您可以使用它来发现任何存储桶的区域,因为 US-Standard 提供了这些信息。
更新/附加
在某些时候,S3 似乎添加了一个新的响应标头x-amx-bucket-region:,它似乎是对 REST API 的无证补充,似乎添加到许多 S3 错误响应中,尤其是 403 错误。
如果您收到错误响应,这似乎是一种有用的自我纠正机制。
此外,上述关于向美国标准区域询问任何存储桶位置的信息仍然准确,如果将相同的请求发送到任何区域 S3 REST 端点,而不仅仅是美国标准,因为所有区域知道所有其他存储桶的位置:例如https://s3-us-west-2.amazonaws.com/bucket-name?location 会询问 US-West-2(俄勒冈),它也有相同的可用信息,用于全球任何存储桶。在某些情况下可能需要询问您最近的区域。