使用我自己的域/子域生成AWS S3 PreSigned URL

时间:2015-04-27 16:37:07

标签: amazon-s3 pre-signed-url

我正在使用AWS SDK for .NET,我目前正在为我的S3存储桶生成预签名网址。

我目前获得的网址类似于https://{bucketname}.s3.amazonaws.com/{FileAndQueryParameters}

我所寻找的是https://{MyDomainName}/{FileAndQueryParameters}

我已经尝试用我自己的CNAME替换第一个网址指向{bucketname}.s3.amazonaws.com,但我得到了明显的

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

任何想法如何实现这一目标?

顺便说一句,这是我现在正在使用的代码:

(...)
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;

2 个答案:

答案 0 :(得分:0)

存储桶名称必须与域相同。

答案 1 :(得分:0)

花了几天时间试图为预签名 URL 设置自定义 CNAME/主机,但似乎不可能。

所有论坛都说这无法完成,或者您必须重新编码整个应用程序才能改用 cloudfront。

将我的 DNS 更改为从 MYBUCKET.s3-WEBSITE-eu-west-1.amazonaws.com 指向 MYBUCKET.s3-eu-west-1.amazonaws.com 立即修复了它。

希望这对其他人有帮助。

工作代码:

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";

        } 
    }