访问 S3 预签名时的 SignatureDoesNotMatch url

SignatureDoesNotMatch when accessing the S3 pre-signed url

我创建了一个 Lambda 函数来为移动应用程序用户生成预签名 URL 以访问 S3 上的 pdf 文档(不是 public)。

s3 = boto3.client('s3')
    resp = s3.list_objects(
        Bucket='xxxxxxxxx',
        EncodingType='url',
        MaxKeys=1,
        Prefix='2',
        RequestPayer='requester'
    )
    key = resp['Contents'][0]['Key']
    url = s3.generate_presigned_url(
        ClientMethod='get_object',
        Params={
            'Bucket': 'xxxxxxxxx',
            'Key': key,
            'SSECustomerAlgorithm': 'AES256',
            'ResponseContentType': 'application/pdf'
            },
        ExpiresIn=3600,
        HttpMethod='GET'
        )

然后我在浏览器上得到这个。

<Error>
<Code>SignatureDoesNotMatch</Code>
<Message>
The request signature we calculated does not match the signature you provided. Check your key and signing method.
</Message>

据我了解,它可以通过 HTTP 请求访问。

有卷曲

curl -X GET https://pre-signedurlhere --output test.pdf

然后

The file “test.pdf” could not be opened. It may be damaged or use a file format that Preview doesn’t recognise.

我不知道使用 list_objects_v2 是否有任何效果,但我最终设法使用以下代码从预签名 url 获得了对文件的访问权限。未更改 AWS 上的任何设置。

    s3 = boto3.client('s3')
    resp = s3.list_objects_v2(
        Bucket='Bucket-name-here',
        MaxKeys=1,
        Prefix='2',
        RequestPayer='requester'
    )
    key = resp['Contents'][0]['Key']
    url = s3.generate_presigned_url(
        ClientMethod='get_object',
        Params={
            'Bucket': '',
            'Key': key,
            'ResponseContentType': 'application/pdf'
            },
        ExpiresIn=3600,
        HttpMethod='GET'
        )