I have the following code (almost the same as this docs page):
private static AmazonS3Client GetS3Client()
{
var credentials = new BasicAWSCredentials(accessKey, secretKey);
return new AmazonS3Client(credentials, new AmazonS3Config
{
ServiceURL = "xxxx",
});
}
public static string GeneratePreSignedUrl(string fileName, TimeSpan expiry, string bucketName)
{
using (AmazonS3Client client = GetS3Client())
{
var request = new GetPreSignedUrlRequest
{
BucketName = bucketName,
Key = fileName,
Verb = HttpVerb.GET,
Expires = DateTime.UtcNow.Add(expiry),
};
return client.GetPreSignedURL(request);
}
}
If I use AWS S3 (without the ServiceURL) to load an image url, GeneratePreSignedUrl
works with no problem and the image is visible in the browser. However, if I use cloudflare R2, visiting the generated url shows the following:
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<Error>
<Code>Unauthorized</Code>
<Message>SigV2 authorization is not supported. Please use SigV4 instead.</Message>
</Error>
I don't know what this message means. However, here it says that SigV4 isn't supported?
Also, I have checked that the GetObjectAsync
method works, so it's not as if I can't use the aws sdk with R2 at all, but GetPreSignedURL
isn't working.
What should I do? Thanks.
I had to do the following:
private static AmazonS3Client GetS3Client()
{
AWSConfigsS3.UseSignatureVersion4 = true;
var credentials = new BasicAWSCredentials(accessKey, secretKey);
return new AmazonS3Client(credentials, new AmazonS3Config
{
ServiceURL = "https://<your_service_url>",
SignatureVersion = "v4",
ForcePathStyle = true,
});
}
Did not have to make any change to the request part in my question. So that remained the same:
public static string GeneratePreSignedUrl(string fileName, TimeSpan expiry, string bucketName)
{
using (AmazonS3Client client = GetS3Client())
{
var request = new GetPreSignedUrlRequest
{
BucketName = bucketName,
Key = fileName,
Verb = HttpVerb.GET,
Expires = DateTime.UtcNow.Add(expiry),
};
return client.GetPreSignedURL(request);
}
}
Thanks to chris05 for part of the answer.