2017-05-29 28 views
1

curlを使用して、aswcli(これは必須)またはアップロード用のboto3を使用せずにs3(eu-central-1)にファイルをアップロードしようとしています。s3へのPUTリクエスト

私は次のように要求に署名するのpythonとbotocoreからいくつかのメソッドを使用しています:この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 

ある

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) 

私は資格で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要求に署名する作業例を持っていますか?

+0

botocoreを使用しますが、boto3は使用しませんか?私はユースケースが何か不思議です。とにかく、Wireshark/'tcpdump 'を使って、boto3からのリクエストがどのように見えるか試してみましたか?そして、あなたは[S3 Curlのサンプルコードとライブラリ](https://aws.amazon.com/code/Amazon-S3?browse=1)を調べましたか? – l0b0

+0

なぜPython自体からリクエストしないのですか? – hjpotter92

+0

@ 10b0、botocoreは署名者であり、boto3はbotocoreを使用するためです。使用例:私はcurlクライアントを要求から置き換えたい –

答えて

0

私はS3のために非同期クライアントを書く方法を見つけました。私はブログ投稿とコードをgithubに公開しました。

関連する問題