将PUT请求签名到s3 [英] Sign PUT request to s3

查看:102
本文介绍了将PUT请求签名到s3的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 curl 进行呼叫,以在s3(eu-central-1)中上传文件,而无需使用aswcli(这是必需条件)或boto3进行上传.

I am trying to do a call with curl to upload a file in s3 (eu-central-1) without using aswcli (this is a requirement) or boto3 for uploading.

我正在使用python和botocore的一些方法对请求进行签名,如下所示:

I am using python and some methods from botocore to sign the request as follow:

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代码的输出为

The output of this python code is

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中的存储桶名称. 该命令的结果是:

I replaced the access_key in Credential= and the bucket name in the url. The result of this command is:

<?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签署放权请求的可行示例?

It seems I miss something. Has anybody a working example of signing a put request to s3?

推荐答案

与此同时,我弄清楚了如何为S3编写异步客户端,并在

I figure out meanwhile how to write an asynchronous client for S3 and I published a blog post and the code on github.

这篇关于将PUT请求签名到s3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆