Pedro G. Dias
Pedro G. Dias

Reputation: 3222

Connecting to Azure Storage Tables in Xamarin

I've a small IoT Project that I'm dwindling with, and it basically just grabs my latest sensor telemetry from my "smart" house and displays it on the form in a very standard Xamarin Application.

My questions are around the use of Xamarin and Azure.Storage:

I have 3 tables that I download in my app:

public DeviceReadingsReader()
{
    _deviceReadingsTable = TableClient.GetTableReference("DeviceReadings");
    _locationsTable = TableClient.GetTableReference("Locations");
    _goalsTable = TableClient.GetTableReference("TemperatureGoals");
}

As you can tell, they all Reference a TableClient which I found using an older, PCL-compatible NuGet package (one question: why aren't the newest azure.storage packages able to install in Xamarin.Forms??)

On UWP and iOS, I have no problem doing this:

    var cloudStorageAccount = CloudStorageAccount.Parse(connectionstring);
    _tableClient = storageAccount.CreateCloudTableClient();

However, when I run this code on Android, I get an exception demmanding that I use a SAS token instead, so I created a SaS token in the Azure portal for the Storage Account, With a 2 year duration, and use it like so:

However, running this on Android, iOS, or UWP gives me an authorization failed Message, indicating that my SaS token is invalid.

Does anyone know what I am doing wrong, and how to Write a piece of code that will actually execute on all 3 platforms?

var sas = "https://0000000000000.table.core.windows.net/?sv=2016-05-31&ss=bfqt&srt=sco&sp=rwdlacup&se=2019-03-08T23:51:51Z&st=2017-03-08T15:51:51Z&spr=https&sig=0000000000000000000000000000000000000000000000&comp=list&restype=table";
StorageCredentials creds = new StorageCredentials(sas);
CloudStorageAccount cloudStorageAccount = new CloudStorageAccount(creds, null, null, new Uri("https://0000000000000.table.core.windows.net/"), null);
_tableClient = cloudStorageAccount.CreateCloudTableClient();           

Edit: I'm aware that I could make a cloud API to retrieve the same values, and all of this would go away, but this is JUST getting values from a Storage table, and I really don't see the need to create an inbetween WebApi for it

Here's the exception:

<RequestResult>
  <HTTPStatusCode>403</HTTPStatusCode>
  <HttpStatusMessage>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.</HttpStatusMessage>
  <TargetLocation>Primary</TargetLocation>
  <ServiceRequestID>926f8520-0002-0033-02b2-98bab7000000</ServiceRequestID>
  <ContentMd5 />
  <Etag />
  <RequestDate>Thu, 09 Mar 2017 09:55:29 GMT</RequestDate>
  <StartTime>Thu, 09 Mar 2017 08:55:28 GMT</StartTime>
  <EndTime>Thu, 09 Mar 2017 08:55:30 GMT</EndTime>
  <Error>
    <Code>AuthenticationFailed</Code>
    <Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:926f8520-0002-0033-02b2-98bab7000000
Time:2017-03-09T08:55:32.7622395Z</Message>
  </Error>
  <ExceptionInfo>
    <Type />
    <HResult>-2147467259</HResult>
    <Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.</Message>
    <Source>Microsoft.WindowsAzure.Storage</Source>
    <StackTrace>  at Microsoft.WindowsAzure.Storage.Core.Executor.Executor+&lt;ExecuteAsyncInternal&gt;d__0`1[T].MoveNext () [0x007eb] in &lt;03db1448eaed4d018343fcf0153c030d&gt;:0 </StackTrace>
  </ExceptionInfo>
</RequestResult>

Upvotes: 2

Views: 677

Answers (1)

Gaurav Mantri
Gaurav Mantri

Reputation: 136196

So there's an issue with the way you're using the SAS. You're using the SAS URL. Please use only the querystring portion:

So your SAS Should be something like:

var sas = "?sv=2016-05-31&ss=bfqt&srt=sco&sp=rwdlacup&se=2019-03-08T23:51:51Z&st=2017-03-08T15:51:51Z&spr=https&sig=0000000000000000000000000000000000000000000000";

Give this one a try.

Upvotes: 2

Related Questions