Reputation: 3222
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+<ExecuteAsyncInternal>d__0`1[T].MoveNext () [0x007eb] in <03db1448eaed4d018343fcf0153c030d>:0 </StackTrace>
</ExceptionInfo>
</RequestResult>
Upvotes: 2
Views: 677
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