2017-09-22 64 views
0

我有以下從第三方應用aws s3 api終點403禁止對於Amazon S3把API上傳文件中的Rails應用程序

https://xxx.s3.amazonaws.com/uploads/74d75512c28b49358846f959bd798536?Signature=lxBIZJD7DN4QK3LPmsHxR7D2eTA%3D&Expires=1506108780&AWSAccessKeyId=AKIAJG6Z6A5TUL7ULPXA 

我試圖讓一個PUT request這個網址到upload an File,但總能得到以下error

#<Net::HTTPForbidden 403 Forbidden readbody=true> 

更新這裏是響應主體

<?xml version="1.0" encoding="UTF-8"?> 
<Error> 
    <Code>SignatureDoesNotMatch</Code> 
    <Message> 
     The request signature we calculated does not match the 
     signature you provided. Check your key and signing method. 
    </Message> 
    <AWSAccessKeyId>AKIAJG6Z6A5TUL7ULPXA</AWSAccessKeyId> 
    <StringToSign> 
    PUT 

    application/xml 
    1506144576 
    /xxx/uploads/93a64f8081804604be917b4185c5ed58 
    </StringToSign> 
    <SignatureProvided>8pwtC2vtN4LuOwGc887AlT2ZnUc=</SignatureProvided> 
    <StringToSignBytes>50 55 </StringToSignBytes> 
    <RequestId>B2B18369BA23A92F</RequestId> 
    <HostId>YCtjOJsfskITKxjW96ouZq1BV=</HostId> 
</Error> 

如果我inspectresponse它顯示以下data,但不明白這是什麼問題?沒有其他線索,任何人都可以幫助將不勝感激。

{ 
"x-amz-request-id" => [ 
    [0] "385D5CADFE6175FC" 
], 
     "x-amz-id-2" => [ 
    [0] "4uD51Gb/rJy0QooQVmF25Qbp0E568bB9v1P4Grg9CTM2dJ/Iiccad/IyuuEnWDphlGZrr8ZUnQw=" 
], 
    "content-type" => [ 
    [0] "application/xml" 
], 
"transfer-encoding" => [ 
    [0] "chunked" 
], 
      "date" => [ 
    [0] "Fri, 22 Sep 2017 19:28:01 GMT" 
], 
      "server" => [ 
    [0] "AmazonS3" 
] 
} 

我運行下面的代碼片段

uri = URI.parse(aws_api_end_point) 
request = Net::HTTP::Put.new(uri) 

request.body = File.read(file_path) 
request.content_type = 'application/xml' 

http = Net::HTTP.start(uri.host, uri.port, :use_ssl => true) 
response = http.request(request) 

注::我沒有使用任何AWS SDK。

+0

*如果我檢查響應,它顯示下列數據*沒有什麼有趣的東西,那裏。但是,如果您可以提取它並向我們顯示,那麼在錯誤響應中也可能有用** body **。 –

+0

謝謝@ Michael-sqlbot,我已經更新了響應正文的問題,它顯示簽名不匹配。但我想知道第三方是否發給我們錯誤的簽名。 –

回答

1

請求籤名是確定性的 - 對於特定時間的給定請求,只有一個有效簽名。對於所有的實際目的而言,情況正好相反 - 對於任何簽名,只能提出一個有效請求。還有其他什麼,和簽名不符。

該算法的設計目的不是反向工程,所以當他們給你簽名時,我們不能說他們期望你做出什麼請求。

但是,我們確實有這個。我相信一些空白丟了,所以我在加回:

<StringToSign> 
    PUT 

    application/x-www-form-urlencoded 
    1506144576 

    /xxx/uploads/93a64f8081804604be917b4185c5ed58 
</StringToSign> 

這是你提出的要求(不是你預計將發出請求),使用這種僞轉換成其canonical form

StringToSign = 
    HTTP-VERB + "\n" + 
    Content-MD5 + "\n" + 
    Content-Type + "\n" + 
    Expires + "\n" + 
    CanonicalizedAmzHeaders + 
    CanonicalizedResource; 

的問題,最明顯的候選人是Content-Type。由於S3 PUT對象操作不使用HTML表單上傳,因此他們不希望您使用application/x-www-form-urlencoded幾乎是肯定的。 S3 PUT預計請求正文中對象的原始八位字節和一個Content-Type標題匹配。 S3本身並沒有真正驗證它們是否匹配(標頭與正文),但沒有至少預期的標頭,上傳將被阻止。

如果您向第三方API提供Content-Type,那麼您的上傳需要在S3上傳中使用相同類型,因爲簽名需要它。

不幸的是,出於故障排除的目的,有無數的事情可以做錯,以使預期與預先簽名的URL一起使用的請求無效。來自第三方的文檔應該闡明他們希望您製作的後續請求的結構。

+0

非常感謝這樣一個很好的答案,是的,我已經消除了格式化響應的一些空間,我也更新了發送內容類型後的問題和響應,這還沒有工作,試圖與第三方聯繫,謝謝 :) –

相關問題