我正在尝试使用 curl 拨打电话来上传s3(eu-central-1)中的文件,而不使用aswcli(这是一项要求)或boto3进行上传。
我正在使用python和botocore的一些方法来签署请求,如下所示:
import datetime
from botocore.credentials import Credentials
from botocore.handlers import calculate_md5
from botocore.awsrequest import AWSRequest
from botocore.auth import S3SigV4Auth
if __name__ == "__main__":
access_key = '<ACCESS>'
secret_key = '<SECRET>'
bucket = 'mybucket'
region = 'eu-central-1'
host = 's3.eu-central-1.amazonaws.com'
SIGV4_TIMESTAMP = '%Y%m%dT%H%M%SZ'
datetime_now = datetime.datetime.utcnow()
xamzdate = datetime_now.strftime(SIGV4_TIMESTAMP)
auth_time = xamzdate[0:8]
filename = 'img.jpg'
f = open(filename, 'rb')
body = f.read()
req = {
'body': body,
'headers': {}
}
calculate_md5(req)
contentMd5 = req['headers']['Content-MD5']
url = 'https://{host}/{bucket}'.format(host=host, bucket=bucket)
params = {'encoding-type': 'url'}
headers = {
'Content-MD5': contentMd5,
'X-Amz-Date': xamzdate, # '20170529T120930Z'
'X-Amz-Content-SHA256': 'UNSIGNED-PAYLOAD',
'X-Amz-Acl': 'public-read',
}
request = AWSRequest('PUT', url, data=body, params=params, headers=headers)
credentials = Credentials(secret_key=secret_key, access_key=access_key)
signer = S3SigV4Auth(credentials=credentials, service_name='s3', region_name=region)
signer.add_auth(request)
signature = request.headers['X-Amz-Content-SHA256']
auth = 'AWS4-HMAC-SHA256 Credential={access_key}/{auth_time}/eu-central-1/s3/aws4_request, ' \
'SignedHeaders=content-md5;host;x-amz-acl;x-amz-content-sha256;x-amz-date, ' \
'Signature={signature}'.format(access_key=access_key,
auth_time=auth_time,
signature=signature,)
print """
curl -X PUT -T "{filename}" \
-H "X-Amz-Date: {xamzdate}" \
-H "Content-MD5: {contentMd5}" \
-H "X-Amz-Content-SHA256: UNSIGNED-PAYLOAD" \
-H "X-Amz-Acl: public-read" \
-H "Authorization: {auth}" \
https://{host}/{bucket}/{filename}
""".format(host=host, bucket=bucket, xamzdate=xamzdate, contentMd5=contentMd5,
filename=filename, auth=auth)
此python代码的输出是
curl -X PUT -T "img.jpg" -H "X-Amz-Date: 20170529T143549Z" -H "Content-MD5: 9WXctE9k50XC/AKwC6yYwQ==" -H "X-Amz-Content-SHA256: UNSIGNED-PAYLOAD" -H "X-Amz-Acl: public-read" -H "Authorization: AWS4-HMAC-SHA256 Credential=<ACCESS_KEY>/20170529/eu-central-1/s3/aws4_request, SignedHeaders=content-md5;host;x-amz-acl;x-amz-content-sha256;x-amz-date, Signature=a54ad95ede0d2ff18272bbded9e1940e71065082056ba7a76c38b45beda1b763" https://s3.eu-central-1.amazonaws.com/MYBUCKET/img.jpg
我替换了Credential中的access_key =和url中的存储桶名称。 该命令的结果是:
<?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>MY ACCESS KEY</AWSAccessKeyId>
<StringToSign>AWS4-HMAC-SHA256
20170529T143549Z
20170529/eu-central-1/s3/aws4_request
8901111961918762ddf496956f95d8ea9bcdb2345dee53ef8c0fb0ec49644464
</StringToSign>
<SignatureProvided>a54ad95ede0d2ff18272bbded9e1940e71065082056ba7a76c38b45beda1b763</SignatureProvided>
<StringToSignBytes>41 57 53 34 2d 48 4d 41 43 2d 53 48 41 32 35 36 0a 32 30 31 37 30 35 32 39 54 31 34 33 35...</StringToSignBytes>
<CanonicalRequest>PUT
/mybucket/img.jpg
content-md5:9WXctE9k50XC/AKwC6yYwQ==
host:s3.eu-central-1.amazonaws.com
x-amz-acl:public-read
x-amz-content-sha256:UNSIGNED-PAYLOAD
x-amz-date:20170529T143549Z
content-md5;host;x-amz-acl;x-amz-content-sha256;x-amz-date
UNSIGNED-PAYLOAD
</CanonicalRequest>
<CanonicalRequestBytes>50 55 54 0a 2f 72 7a 76 65 75 63 65 6e 74 72 61 6c 31 2f 69 6d 67...</CanonicalRequestBytes>
<RequestId>BC854A452F8F92A5</RequestId>
<HostId>vDY8VPIO2n/DoTagpEaUANekON0gpWPQrWfVY2QQ09srXRkgX/O3fvgyT2fNdYhiBXQrgs4yoC4=</HostId>
</Error>
似乎我想念一些东西。有没有人向s3签署一个put请求的工作示例?