S3预先签名的下载网址立即过期,为什么?

时间:2016-05-26 09:37:42

标签: amazon-s3

我有app生成预签名网址(使用java sdk generatePresignedUrl方法)。 一切都在一个环境(@ EU_central_1服务器)上运行,但在其他环境(客户端的EU_West_1)上发布的相同应用程序会生成无法正常工作的链接,当我尝试在创建后立即下载对象时来自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>

正如您所看到的,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);

看起来两台服务器同时返回。这是来自同一区域的连接到两个不同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>
来自具有预先签名的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>

同时创建两个链接(页面刷新时间差为几秒)

2 个答案:

答案 0 :(得分:4)

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

生成V4签名(正如您所做)要求您知道现在的时间,并将该值包含为X-Amz-Date。 AWS然后在他们身边做数学计算。 &#34;嘿,这个家伙说他11分钟前签了名,而且只有10分钟好了......被拒绝了!&#34;

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

答案 1 :(得分:0)

请参考以下文章以同步您的时间(在ec2和s3之间) https://aws.amazon.com/blogs/aws/keeping-time-with-amazon-time-sync-service/

我们需要使用名为chrony的服务。 其在ntp上的通用实现,并且更准确,更适应leap秒。

使用以下信息进行故障排除:

您可以使用date命令来了解当前linux计算机中的时间。

X-Amz-Date会告诉您何时在运行代码的ec2或计算机中签名了URL。 在答复中,

<Expires>2016-05-31T10:49:54Z</Expires>
<ServerTime>2016-05-31T11:00:07Z</ServerTime>

Expires根据X-Amz-Expires告诉您签名何时过期,ServerTime告诉您接收请求的时间在s3服务器上的时间。