1

I am trying to use refit to upload to azure blob storage from a Xamarin iOS application. This is the interface configuration I am using for Refit:

[Headers("x-ms-blob-type: BlockBlob")]
[Put("/{fileName}")]
Task<bool> UploadAsync([Body]byte[] content, string sasTokenKey,
[Header("Content-Type")] string contentType);

Where the sasTokenKey parameter looks like this:

"/content-default/1635839001660743375-66f93195-e923-4c8b-a3f1-5f3f9ba9dd32.jpeg?sv=2015-04-05&sr=b&sig=Up26vDxQikFqo%2FDQjRB08YtmK418rZfKx1IHbYKAjIE%3D&se=2015-11-23T18:59:26Z&sp=w"

This is how I am using Refit to call the azure blob server:

var myRefitApi = RestService.For<IMyRefitAPI>("https://myaccount.blob.core.windows.net");
myRefitApi.UploadAsync(photoBytes, sasTokenKey, "image/jpeg"

However I am getting the follow error:

Response status code does not indicate success: 403 (Server failed to 
authenticate the request. Make sure the value of Authorization header is 
formed correctly including the signature.)

The SAS url is working fine if I call it directly like this

var content = new StreamContent(stream);
            content.Headers.Add("Content-Type", "jpeg");
            content.Headers.Add("x-ms-blob-type", "BlockBlob");
var task = HttpClient.PutAsync(new Uri(sasTokenUrl), content);
task.Wait();

So basically I am just trying to do the same thing using Refit. Any idea how to get Refit working with Azure Blob Storage?

Thanks!

[UPDATE] I am now able to upload the bytes to the azure blob server but something seems to be wrong with the byte data because I am not able to view the image. Here is the code I am using to convert to byte array.

byte[] bytes;
using (var ms = new MemoryStream())
{
   stream.Position = 0;
   stream.CopyTo(ms);
   ms.Position = 0;
   bytes = ms.ToArray();
}

[UPDATE] Got it fixed by using stream instead of byte array!

doorman
  • 15,707
  • 22
  • 80
  • 145
  • I don't see how you're using the SAS token in the refit code. Could you include that portion or add some comments to clarify? – Emily Gerner Nov 23 '15 at 18:11
  • Hi @Emily please see the clarified question above! – doorman Nov 23 '15 at 18:37
  • 1
    I don't know anything about refit in the slightest, but have you tried sending the sas token not encoded? I see %2F and %3D and I'm curious if refit is encoding those a second time. – Emily Gerner Nov 23 '15 at 18:41
  • I am now able to blob the bytes :) but I am not able to view the image so it seems there is something wrong with the bytes I am blobbing. I added the code which shows I am converting from stream to bytes array. See the updated question. – doorman Nov 23 '15 at 22:30
  • Posted my comment as an answer since it looks like I guessed right. :) – Emily Gerner Nov 24 '15 at 18:19

2 Answers2

1

I see %2F and %3D and I'm curious if refit is encoding those a second time. Try sending the token without encoding it.

Emily Gerner
  • 2,427
  • 16
  • 16
0

This is incorrect use of Authorization header. You use Authorization header when you want to authorize the requests using account key. If you have the Shared Access Signature then you really don't need this header as the authorization information is included in the SAS itself. You can simply use the SAS URL for uploading files.

Gaurav Mantri
  • 128,066
  • 12
  • 206
  • 241
  • Hi Gaurav, I updated my question and changed the interface configuration to use the SAS url. However I am still getting error about the authorization. I would prefer to use Refit since I am using it for all my other REST endpoints. I think I am just setting the wrong configuration. – doorman Nov 21 '15 at 20:05
  • Unfortunately I am not aware of Refit that you're using. Would you mind sharing a link about that so that I can read up more about it. However looking at the error, I think there's something wrong with your SAS token itself. Please check for the following things: 1) SAS has not expired 2) SAS has `write` permissions. Also please share the code for getting the SAS token itself. – Gaurav Mantri Nov 21 '15 at 20:16
  • I made some updates. Please see the link to Refit documentation at top. The SAS token is working fine if I call it directly... see code updates at the bottom. – doorman Nov 21 '15 at 20:28