Мне нужно загрузить файлы в S3 с машины, на которой должны установить неправильные часы, и смещение от правильного времени будет меняться.По-видимому, это можно сделать, указав заголовок X-Amz-Date
(установив его в текущее фактическое время) и загрузив его с помощью авторизации строки запроса.Драгоценный камень aws-sdk
Ruby не предоставляет этот параметр в методе presigned_url
, поэтому я пытаюсь сделать это, используя гем aws-sigv4
.Мои PUT
s, однако, отклоняются с ошибками 403 Unauthorized
.
Вот код, который я пробовал:
def upload_file_with_time(file, file_path, expires_in_seconds, time)
region = "us-east-1"
access_key_id = ENV['AWS_ACCESS_KEY_ID']
secret_access_key = ENV['AWS_SECRET_ACCESS_KEY']
obj = s3_bucket.object(file_path)
signer = Aws::Sigv4::Signer.new(
service: 's3',
region: region,
access_key_id: access_key_id,
secret_access_key: secret_access_key
)
pre_signed_url = signer.presign_url(
http_method: 'PUT',
url: obj.public_url,
expires_in: expires_in_seconds,
time: time
)
Net::HTTP.start(pre_signed_url.host) do |http|
http.send_request("PUT", pre_signed_url.request_uri, file, "content-type": "")
end
end
Код генерирует предварительно назначенный URL-адрес, например так:
https://XXXXX.s3.amazonaws.com/testing/89254661-24de-4bc7-b6e1-7d0018213735.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=XXXXX%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20190301T213824Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host&X-Amz-Signature=XXXXX
(конфиденциальная информация была отредактирована с помощью XXXXX
).
Я получаю 403 Unauthorized
из http.send_request
, когда я пытаюсь загрузить эту конечную точку.Если я нажму на URL с сообщением от curl
, я вижу это как начало ответа XML:
<?xml version=“1.0”?>
<Error>
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
Что я делаю не так?