S3 预签名下载 url 立即过期,为什么?

raz*_*zor 5 amazon-s3

我有生成预签名 url 的应用程序(使用 java sdk generatePresignedUrl 方法)。一切都在一个环境(@ EU_central_1 服务器)上运行,但在其他环境(客户端的 EU_West_1)上发布的同一个应用程序生成的链接不起作用,当我尝试在创建 URL 后立即下载对象时,来自 S3 的信息:

<Error>
   <Code>AccessDenied</Code>
   <Message>Request has expired</Message>
   <X-Amz-Expires>600</X-Amz-Expires>
   <Expires>2016-05-26T09:32:44Z</Expires>
   <ServerTime>2016-05-26T09:33:03Z</ServerTime>
Run Code Online (Sandbox Code Playgroud)

如您所见,x-amz-expires 设置为 600 秒,但 expires 标记表示对象已立即过期。

GeneratePresignedUrlRequest.setExpiration计算不正确的到期时间是否有问题 ?

这是我设置过期时间的代码:

    Date expiration =  new Date();
    expiration.setTime(expiration.getTime() + 1000 * 600);
    GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, key);
    generatePresignedUrlRequest.setMethod(HttpMethod.GET);
    generatePresignedUrlRequest.setExpiration(expiration);
    URL url = s3client.generatePresignedUrl(generatePresignedUrlRequest);
Run Code Online (Sandbox Code Playgroud)

看起来两台服务器同时返回。这是来自连接到同一区域的两个不同 S3 服务器的两个不同 EC2 服务器的响应。一个的过期时间设置为 4,第二个设置为 4000(以便能够在创建链接后立即下载资源)。

来自服务器正常工作的响应:

<Error>
   <Code>AccessDenied</Code>
   <Message>Request has expired</Message>
   <X-Amz-Expires>4</X-Amz-Expires>
   <Expires>2016-05-31T09:54:04Z</Expires>
   <ServerTime>2016-05-31T11:00:17Z</ServerTime>
Run Code Online (Sandbox Code Playgroud)

来自带有预签名 URL 问题的服务器的响应:

<Error>
   <Code>AccessDenied</Code>
   <Message>Request has expired</Message>
   <X-Amz-Expires>4000</X-Amz-Expires>
   <Expires>2016-05-31T10:49:54Z</Expires>
   <ServerTime>2016-05-31T11:00:07Z</ServerTime>
Run Code Online (Sandbox Code Playgroud)

同时创建的两个链接(页面刷新有几秒钟的差异)

Mic*_*bot 5

签名 V4(与 V2 不同)不依赖签名生成代码进行时间数学运算来计算到期时间。

生成 V4 签名(正如您正在做的那样)要求您知道现在是什么时间,并将该值包含为X-Amz-Date. 然后 AWS 会替他们做数学计算。“哎,这家伙说11分钟前就签了,而且只签了10分钟……拒绝!”

检查生成签名的机器上的时钟。

  • 不,看起来是您服务器上的时钟有问题。正确设置时钟,你会好起来的。`sudo apt-get install ntp`。如果您检查签名 URL 中的“X-Amz-Date”——*应该是*您实际签署它的时间——并且它已经过去了几分钟,这证实了问题。 (2认同)