boto3: generate_presigned_url no longer works, gives: SignatureDoesNotMatch
import boto3,requests,os
def get_session():
access_key = os.getenv('JAR_LAMBDA_ACCESS_KEY')
secret_key = os.getenv('JAR_LAMBDA_SECRET_KEY')
if None in [access_key, secret_key]:
raise Exception('KEYs not set')
session = boto3.Session(aws_access_key_id=access_key, aws_secret_access_key=secret_key, region_name='eu-central-1')
return session
def print_url():
key = 'mykey'
bucket = 'mybucket'
try:
session = get_session()
s3 = session.client('s3', config=boto3.session.Config(signature_version='s3v4'), region_name='eu-central-1')
url = s3.generate_presigned_url(ClientMethod='get_object', Params={'Bucket': bucket, 'Key': key}, ExpiresIn=3600)
print(url)
resp = requests.get(url)
print(resp)
except Exception as e:
print(e)
The browser gives a 403 and:
<Error>
<Code>SignatureDoesNotMatch</Code>
<Message>
The request signature we calculated does not match the signature you provided. Check your key and signing method.
</Message>
...
Signing with:
aws s3 presign s3://mybuket/mykey --expires 1800 --profile presigner
works perectly. The presigner profile has the same keys as the python code above.
Versions: Python 3.7.0 (had the same issue with 3.6.*) boto3-1.7.70 botocore-1.10.70 s3transfer-0.1.13
Please also read this: https://stackoverflow.com/questions/50213740/aws-s3-presigned-urls-with-boto3-signature-mismatch
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 7
- Comments: 21 (2 by maintainers)
@imperio59 's answer helped, but I also needed to set
signature_version='s3v4':boto3 1.9.28 (1.9.34 is latest available) botocore 1.12.28 (1.12.34 is latest available) python 3.6.4 (MacOS)
Thanks @Trogious ! We had the same issue
SignatureDoesNotMatchuploading an image from our React Native APP.I fixed it passing the
signature_version='s3v4'and theregion_nameAfter several hours of hitting this same issue, changing the addressing_style to ‘path’ made everything work for me, including custom headers…
See docs here: https://boto3.amazonaws.com/v1/documentation/api/latest/guide/s3.html#changing-the-addressing-style
I needed BOTH
s3v4andaddressing_style:pathin my Config() for it to work with boto3.… and then the functional part …
Not sure how to make the URL last 7 days as requested. That has to do with the IAM I used, but working on it.
Without addressing_style: path I get this log:
Which generates this url:
Which when opened redirects to this url:
Where CanonicalRequest changes the host too:
For some reason the code uses
host:bucket.s3.amazonaws.comwhile S3 expectshost:bucket.s3.eu-central-1.amazonaws.com.When I initialize the client with region specified, the local canonical host is still the same:
host:bucket.s3.amazonaws.comEdit: got it working with
config=Config(s3={"addressing_style": "virtual"})@lu1s There’s nothing inherently wrong with either of those URLs you posted previously, just that they’re using two different signature versions.
It is possible that switching from
virtualtopathaddressing style could fix pre-signed URLs signed using SigV4. For SigV4 the host is signed as part of the signature, which can cause problems for newly created buckets whenvirtualaddressing style is being used. S3 will redirect to a different host for buckets that DNS haven’t propagated for, which leads signature mismatch errors as the host is no longer correct. My hunch is that this is the case most people are running into.It’s also worth nothing that some regions only support SigV4 and you’ll need to ensure that you’re using it for those regions.
Using the latest version of boto3 I was able to successfully generate and use a presigned URL created with all permutations of SigV2/SigV4 and path/virtual addressing style for a bucket that existed for quite some time.
Let me know if that clears things up.