【问题标题】:Uploading to Amazon S3 via curl route通过 curl 路由上传到 Amazon S3
【发布时间】:2020-12-02 02:29:50
【问题描述】:

我正在尝试通过 Spring Boot 设置文件上传 REST API。

我目前有一个列表/GET 方法curl http://localhost:8080/api/aws/s3/list,它返回存储桶中当前存在的对象列表。

对于上传,我一直在尝试:

curl -F "data=@test.txt" http://localhost:8080/api/aws/s3/upload -i

产生:

HTTP/1.1 100 Continue

HTTP/1.1 200 OK
Date: Sun, 25 Jun 2017 23:28:36 GMT
X-Application-Context: application
Content-Type: application/json;charset=utf-8
Transfer-Encoding: chunked

但是当我查看存储桶时,它并没有被新文件更新。

这会是 AWS 上的权限问题吗?只有我的帐户具有读写权限。我创建的用户和组具有管理员权限。我没有添加存储桶策略。这是我的 CORS 配置:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>DELETE</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
</CORSConfiguration>

这是我的 S3 控制器在春季的上传部分:

@RequestMapping(value = "/upload", method = RequestMethod.POST)
public List<PutObjectResult> upload(@RequestParam("file") MultipartFile[] multipartFiles) {
    return s3Wrapper.upload(multipartFiles);
}

【问题讨论】:

    标签: spring amazon-web-services curl amazon-s3


    【解决方案1】:

    您应该为 S3 指定您使用的存储桶名称和一些参数。我猜它是 PUT,而不是 POST。互联网上有几个命令行示例。

    file=/path/to/file/to/upload.tar.gz
    bucket=your-bucket
    resource="/${bucket}/${file}"
    contentType="application/x-compressed-tar"
    dateValue=`date -R`
    stringToSign="PUT\n\n${contentType}\n${dateValue}\n${resource}"
    s3Key=xxxxxxxxxxxxxxxxxxxx
    s3Secret=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    signature=`echo -en ${stringToSign} | openssl sha1 -hmac ${s3Secret} -binary | base64`
    curl -X PUT -T "${file}" \
      -H "Host: ${bucket}.s3.amazonaws.com" \
      -H "Date: ${dateValue}" \
      -H "Content-Type: ${contentType}" \
      -H "Authorization: AWS ${s3Key}:${signature}" \
      https://${bucket}.s3.amazonaws.com/${file}
    

    【讨论】:

    【解决方案2】:
        #run this code on ec2 linux with s3 write role 
    
    TOKEN=`curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
    xamztoken=`curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/ec2files3 | jq -r ".Token"`
    
    
    yyyymmdd=`date +%Y%m%d`
    s3Bucket="testfiles3bc"
    bucketLocation="us-east-1"
    s3SecretKey=`curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/ec2files3 | jq -r '.SecretAccessKey'`
    s3AccessKey=`curl -s -H "X-aws-ec2-metadata-token: $TOKEN"  http://169.254.169.254/latest/meta-data/iam/security-credentials/ec2files3 | jq -r ".AccessKeyId"`
    endpoint="testfiles3bc.s3.amazonaws.com"
    fileName="image.gif"
    contentLength=`cat ${fileName} | wc -c`
    contentHash=`openssl sha -sha256 -hex ${fileName} | sed 's/.* //'`
    contentType=`file -b --mime-type $fileName`
    b64=`openssl md5 -binary "$fileName" | openssl base64`
    acl="private"
    
    date=`date -u +%Y%m%dT%H%M%SZ`
    
    expdate_s="2022-12-30T12:00:00.000Z"
    
    region="us-east-1"
    
    
    p=$(cat <<POLICY | openssl base64 | tr -d \\n
    { "expiration": "${expdate_s}T12:00:00.000Z",
      "conditions": [
        {"acl": "$acl" },
        {"bucket": "$s3Bucket" },
        ["starts-with", "\$key", ""],
        ["starts-with", "$contentType", "image/"],
        {"x-amz-date": "$date" },
        {"content-md5": "$b64" },
        {"x-amz-credential": "${s3AccessKey}/${yyyymmdd}/${region}/s3/aws4_request" },
        {"x-amz-security-token": "${xamztoken}" },
        {"x-amz-algorithm": "AWS4-HMAC-SHA256" }
      ]
    }
    POLICY
    )
    
    
    stringToSign=$p
    echo "----------------- canonicalRequest --------------------"
    echo -e ${canonicalRequest}
    echo "----------------- stringToSign --------------------"
    echo -e ${stringToSign}
    echo "-------------------------------------------------------"
    
    
    
    # calculate the signing key
    DateKey=`echo -n "${yyyymmdd}" | openssl sha -sha256 -hex -hmac "AWS4${s3SecretKey}" | sed 's/.* //'`
    DateRegionKey=`echo -n "${bucketLocation}" | openssl sha -sha256 -hex -mac HMAC -macopt hexkey:${DateKey} | sed 's/.* //'`
    DateRegionServiceKey=`echo -n "s3" | openssl sha -sha256 -hex -mac HMAC -macopt hexkey:${DateRegionKey} | sed 's/.* //'`
    SigningKey=`echo -n "aws4_request" | openssl sha -sha256 -hex -mac HMAC -macopt hexkey:${DateRegionServiceKey} | sed 's/.* //'`
    # then, once more a HMAC for the signature
    signature=`echo -en ${p} | openssl sha -sha256 -hex -mac HMAC -macopt hexkey:${SigningKey} | sed 's/.* //'`
    
    
    key_and_sig_args="-F X-Amz-Credential=${s3AccessKey}/${yyyymmdd}/${region}/s3/aws4_request -F X-Amz-Algorithm=AWS4-HMAC-SHA256 -F X-Amz-Signature=$signature -F X-Amz-Date=${date}"
    
    
    curl -v   \
    -F key=$fileName \
    -F acl=$acl \
    $key_and_sig_args  \
    -F "content-md5= ${b64}" \
    -F "Policy=$p" \
    -F "X-Amz-Security-Token= ${xamztoken}" \
    -F "file=@$fileName" \
    https://${s3Bucket}.s3.amazonaws.com/
    

    【讨论】:

      【解决方案3】:

      这是因为我在控制器中设置的参数是file,但在我的 curl 路由中我一直使用data

      【讨论】:

        猜你喜欢
        • 2012-05-17
        • 2010-12-02
        • 2013-01-12
        • 1970-01-01
        • 2012-01-14
        • 2017-11-21
        • 1970-01-01
        • 2015-05-13
        • 2016-01-26
        相关资源
        最近更新 更多