skip to Main Content

I have created a function to get a link to download an object in S3.

def get_presigned_url(s3_bucket, s3_object_key, expiration_seconds):
     url = boto3.client('s3', config=Config(signature_version='s3v4'),                      
                        aws_access_key_id='access_key_id',
                        aws_secret_access_key='secret_access_key').generate_presigned_url(
                        ClientMethod='get_object',
                        Params={'Bucket': s3_bucket, 'Key': s3_object_key},
                        ExpiresIn=expiration_seconds)
     return url

It creates the link with the correct expiry time (90 hours) but after 20 hours the link stops working.

Can someone help me?

2

Answers


  1. PreSigned URL created using

    1. Console: 1 minute and 12 hours max
    2. AWS CLI or AWS SDKs – max 7 days

    If you created a presigned URL by using a temporary token, then the URL expires when the token expires, even if you created the URL with a later expiration time.

    Ref: https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-presigned-url.html#PresignedUrl-Expiration

    Alternatively, override the session and create a client using that session as below

    import boto3.session
    session = boto3.session.Session(
                      region_name='us-east-1', 
                      aws_access_key_id='aws_access_key_id', 
                      aws_secret_access_key='aws_secret_access_key')
    
    s3_client = session.client('s3', config=Config(signature_version='s3v4'))
    
    url = s3_client.generate_presigned_url(
                        ClientMethod='get_object',
                        Params={'Bucket': s3_bucket, 'Key': s3_object_key},
                        ExpiresIn=expiration_seconds)
    
    Login or Signup to reply.
  2. I’m not sure what’s happening with your code, but here is a sample Python program based on your code:

    import boto3
    from botocore.config import Config
    
    client = boto3.client(
        's3',
        config=Config(signature_version='s3v4'),                      
        aws_access_key_id='AKIA123',
        aws_secret_access_key='secret_access_key'
    )
    
    url = client.generate_presigned_url(
        ClientMethod='get_object',
        Params={'Bucket': 'my-bucket', 'Key': 'my-key'},
        ExpiresIn=900
    )
    
    print(url)
    

    The output is:

    https://my-bucket.s3.amazonaws.com/my-key?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIA123%2F20230630%2Fap-southeast-2%2Fs3%2Faws4_request&X-Amz-Date=20230630T121331Z&X-Amz-Expires=900&X-Amz-SignedHeaders=host&X-Amz-Signature=b9b161e89ad21f63d829b56240cecc5985d149608cc4fc152ae23dc46c38ef3f

    You’ll notice that is is displaying the EXACT Access Key that was passed into the function (AKIA123). Generating a pre-signed URL does not actually involve making a call to AWS. Rather, it is just using a hash function and the Secret Key to ‘sign’ the request.

    Yet, strangely, your code is returning an ASIA key. I think you are not running the code you have shown us. Try running the above code and you’ll see.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search