Reputation: 408
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;
Upvotes: 9
Views: 3505
Reputation: 384
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";
}
}
Upvotes: 4