2016-05-26 35 views
0

我有生成預先登記的URL的應用程序(使用java sdk generatePresignedUrl方法)。 一切工作在一個環境(@ EU_central_1服務器)上,但在其他環境(客戶端的EU_West_1)上發佈的同一應用程序生成不起作用的鏈接,當我嘗試在創建URL後立即下載對象時,來自S3的信息: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秒,但過期標記表示對象已經過期。

是否有問題 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>4000</X-Amz-Expires> 
    <Expires>2016-05-31T10:49:54Z</Expires> 
    <ServerTime>2016-05-31T11:00:07Z</ServerTime> 

兩個鏈接在同一時間創造(與頁面刷新幾秒鐘差)

:從presigned URL問題的服務器

<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> 

響應

回答

2

簽名V4(與V2不同)不依賴簽名生成代碼來計算過期時間。

生成V4簽名(如您所做的那樣)要求您知道它現在是什麼時間現在,並將該值包含爲X-Amz-Date。然後,AWS自己做數學。 「嘿,這個人說他在11分鐘前簽了名,而且只有10分鐘的時間......否認!」

檢查生成簽名的機器上的時鐘。

+0

所以這是亞馬遜SDK的問題? (我已經添加了設置到期時間的代碼) 如何從S3服務器獲取時間? (並計算差異?) – razor

+0

不,它看起來像你的服務器上的時鐘是錯誤的問題。正確設置時鐘,你會很好。 'sudo apt-get install ntp'。如果您在簽名的URL中檢查'X-Amz-Date',那麼*應該是您實際簽名的時間 - 並且已經過了幾分鐘的時間,這確認了問題。 –

+0

兩個服務器具有相同的時間(以錯誤的XML返回): 2016-05-31T08:30:50Z 2016-05-31T08:30:35Z razor