Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate an AWS S3 PreSigned URL using my own domain/subdomain

I'm using AWS SDK for .NET and I am currently generating presigned URLs for my S3 bucket.

The URLs I currently get are like https://{bucketname}.s3.amazonaws.com/{FileAndQueryParameters}

What I was looking for was something like https://{MyDomainName}/{FileAndQueryParameters}

I've already tried to replace the first url with my own CNAME pointing to {bucketname}.s3.amazonaws.com but I get an obvious

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

Any ideas how to accomplish this?


By the way, this is the code I'm using right now:

(...)
AmazonS3 client = AWSClientFactory.CreateAmazonS3Client(AccessKey, SecretKey);

string S3_KEY = Key;
string BUCKET_NAME = Bucket;
string FOLDER = SubFolder;
GetPreSignedUrlRequest request = new GetPreSignedUrlRequest();
request.WithBucketName(BUCKET_NAME);
request.WithKey(FOLDER + "/" + S3_KEY);

if (ssUseHTTPS)
{
    request.WithProtocol(Protocol.HTTPS);
}
else
{
    request.WithProtocol(Protocol.HTTP);
}

if (DownloadFileName != string.Empty)
{
    ResponseHeaderOverrides responseHeaders = new ResponseHeaderOverrides();
    responseHeaders.CacheControl = "No-cache";
    responseHeaders.ContentDisposition = "attachment; filename=" + DownloadFileName.Replace(";", "").Replace(",", "");

    request.ResponseHeaderOverrides = responseHeaders;
}

request.WithExpires(DateTime.Now.AddSeconds(SecondsValidFor));

Url = client.GetPreSignedURL(request);

return Url;
like image 265
pipo Avatar asked Apr 27 '15 16:04

pipo


People also ask

How do I get a Presigned URL on AWS?

To generate a presigned URL using the AWS Management ConsoleIn the Buckets list, choose the name of the bucket that contains the object that you want a presigned URL for. In the Objects list, select the object that you want to create a presigned URL for. On the Actions menu, choose Share with a presigned URL.


1 Answers

Spent days going round in circles trying to setup custom CNAME/host for presigned URLs and it seemed impossible.

All forums said it cannot be done, or you have to recode your whole app to use cloudfront instead.

Changing my DNS to point from MYBUCKET.s3-WEBSITE-eu-west-1.amazonaws.com to MYBUCKET.s3-eu-west-1.amazonaws.com fixed it instantly.

Hope this helps others.

Working code:

function get_objectURL($key) {


        // Instantiate the client.
        $this->s3 = S3Client::factory(array(
            'credentials' => array(
                'key'    => s3_key,
                'secret' => s3_secret,
            ),
            'region'  => 'eu-west-1',
            'version' => 'latest',
            'endpoint' => 'https://example.com',
            'bucket_endpoint' => true,
            'signature_version' => 'v4'
        ));


        $cmd = $this->s3->getCommand('GetObject', [
            'Bucket' => s3_bucket,
            'Key' => $key
        ]);


        try {
        
            $request = $this->s3->createPresignedRequest($cmd, '+5 minutes');

            // Get the actual presigned-url
            $presignedUrl = (string)$request->getUri();

            return $presignedUrl;

        } catch (S3Exception $e) {

            return $e->getMessage() . "\n";

        } 
    }
like image 94
Ryan Avatar answered Oct 07 '22 06:10

Ryan