COS - IBM Cloud - .NET - Generated Presigned URL

58 Views Asked by At

There is some way to generate presigned url for Cloud object storage in ibm cloud?

I tested with examples using java and it generates a url that works, and it generate query params like X-Amz-Algorith...

But when I try do the same using .NET, first, I have to use aws sdk for S3, to manage, and I can do operations like upload/download, but the generatedpresigned url method generates me an url with different query params and if I try use that for download (for example) It does not work (always I get 403 - Forbidden).

Values of query params that generates when I create the presigned url using .NET AWS S3 nuget contains following params:

  • AWSAccessKeyId=<>
  • Expires=<>
  • Signature=<>

But using Java and com.ibm.cloud.objectstorage.services.s3.model, I recover query params like:

  • X-Amz-Algorithm
  • X-Amz-Date
  • X-Amz-SignedHeaders
  • X-Amz-Expires
  • X-Amz-Credential -> it is different that the accesskey of the .net solution (contains metainformation readable in the string)
  • X-Amz-Signature -> it is different (in lenght)

Need to know:

  • if there is a solution for .NET core
    • special package
    • api rest way
    • etc
  • if I could "map" one url to do similar than the correct one if maybe parameters could be equivalent.
1

There are 1 best solutions below

2
Peter Song On

Values of query params that generates when I create the presigned url using .NET AWS S3 nuget contains following params:

AWSAccessKeyId=<> Expires=<> Signature=<>

This suggests that you are using SigV2 instead of SigV4. SigV2 uses query parameters like Expires whereas SigV4 and SigV4A uses X-Amz-Expires.

You are probably configured to use us-east-1 which the AWS .NET SDK treats as the regional endpoint and therefore uses SigV2 by default.

Try setting your region explicitly directly in the client or set the signature version explicitly via the AWSConfigsS3 object.

Setting the region explicitly:

var s3Client = new AmazonS3Client(RegionEndpoint.UsWest1);

forcing SigV4 if you must use us-east-1 via config:

AWSConfigsS3.UseSignatureVersion4 = true;

If you really want to know why the AWS .NET SDK uses SigV2 for us-east-1, here is the explanation from a principal engineer on the aws .NET SDK:

The .NET SDK uses SigV2 for us-east-1 legacy reasons. The last major version of the .NET came out in 2015 when SigV4 was at its early stage and S3 didn't even support it yet. For any other service or region we could swap out the signature version without any breaking change but because the .NET SDK treats us-east-1 as essentially the S3 global endpoint we can't change S3 for us-east-1 to SigV4.

By global endpoint if your client uses s3.amazonaws.com endpoint, which the .NET SDK does for us-east-1 you can make requests for buckets in other regions like us-west-2. That was S3's design since it went multi region. With the introduction with SigV4 this behavior got complicated because the region the bucket is in is required for creating the SigV4 signature. In the normal SDK API calls the SDK maintained compatibly when it switch to SigV4 by first signing with us-east-1 and when it makes the request it detects if the request failed because of a region mismatch, resigns the request to the correct region returned by S3 and then makes the request again. There is caching involved so the SDK only does this double hop once. In the case of a presigned URL the SDK isn't involved to handle this error and redirect case. To avoid breaking any users the SDK has kept using SigV2 by default for us-east-1.

Since creation of presigned URLs are done without any network calls it is impossible for us to know how many users this would impact if we changed the signature version. Without being able to measure the blast radius we have never felt comfortable changing the signature version without doing a major version bump. If we did a major version bump we would make this change but there isn't a plan for a major version bump on the near horizon.