关于SO和其他地方的一些问题和答案概述了解决从boto3 SDK调用“ generate_presigned_url”时引发的SignatureDoesNotMatch错误的可能解决方案。 boto3中很少有人使用,大多数答案都建议您获取新的凭据来解决此异常。您可以看到更多(但这在PHP中)here。
但是这些对我不起作用,因为我使用的是正确的凭据以及正确的存储桶名称和密钥路径。
最初,我打电话给它来生成我的客户端,然后打电话给generate_presigned_url。
client_s3 = boto3.client(
's3',
# Hard coded strings as credentials, not recommended.
aws_access_key_id='XXX',
aws_secret_access_key='XXX',
region_name='us-east-2',
# EDIT: Previously, I used signature_version='v4' here, but as a user here pointed out, this might not work. Regardless, I tried 's3v4' prior to trying 'v4' and neither worked for me.
config=Config(signature_version='s3v4')
)
url = client_s3.generate_presigned_url(
ClientMethod='get_object',
Params={
'Bucket': 'BUCKET_NAME',
'Key': 'CORRECT_KEY'
}
)
当使用的所有参数看似正确时,什么会造成此错误?我该如何解决?
答案 0 :(得分:2)
documentation of boto3中明确提到该选项应类似于config=Config(signature_version='s3v4')
。 v4
不起作用。
这是boto3文档的示例。
import boto3
from botocore.client import Config
# Get the service client with sigv4 configured
s3 = boto3.client('s3', config=Config(signature_version='s3v4'))
# Generate the URL to get 'key-name' from 'bucket-name'
url = s3.generate_presigned_url(
ClientMethod='get_object',
Params={
'Bucket': 'bucket-name',
'Key': 'key-name'
}
)
顺便说一句,us-east-2
仅允许签名版本4,因此您无需指定它。 See This。
答案 1 :(得分:1)
我知道回答有点晚了,但我按照 this GitHub 链接中指定的方法解决了我的问题。
import boto3
import requests
parts = s3_client.generate_presigned_post(Bucket=bucket_name,
Key=key,
Fields={
'acl': 'public-read',
'Content-MD5': str(md5),
'Content-Type': 'binary/octet-stream'
},
Conditions=[
{"acl": "public-read"},
["starts-with", "$Content-Type", ""],
["starts-with", "$Content-MD5", ""]
]
)
url = parts['url']
data = parts['fields']
files = {'file': open(local_path, 'rb')} # the key supposed to be file may be
response = requests.post(url, data=data, files=files)
答案 2 :(得分:0)
看到此AWS forum之后,我发现可能会发生一些麻烦,但是我真的只是想用一个安全的解决方案来解决问题。
我的分辨率绝对不是每个人都最佳,但是对我有用。
我将“ us-east-2”中存储桶中的所有内容复制到“ us-east-1”中的新存储桶中,并且能够使用完全相同的访问/秘密密钥和存储桶/密钥正确访问该存储桶路径。我只是用:
client_s3 = boto3.client(
's3',
# Hard coded strings as credentials, not recommended.
aws_access_key_id='XXX',
aws_secret_access_key='XXX'
)
如果您像我一样,并且不想花费数小时来尝试破译AWS的不良文档,则可以这样做。如果您有 real 解决方案,请在此处添加。
我仍然不确定是什么原因造成的,但可能与“ v4”签名方法有关,该方法依赖于区域。