0
votes

I am working on a POC where I have to create a simulated device and connected to IOT HUB , this part is done after this some external application sends message to IOT HUB for that device.

Message contains the blob storage SAS URI, this same file I need to download to device.

Simulated device able to get the SAS URI and but when I am start downloading the file below error I am getting.

Exception in thread "main" com.microsoft.azure.storage.StorageException: Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.

Rectify me if my approach is wrong and correct me with appropriate approch for this use case.

private static void download(String message) throws StorageException, IOException, JSONException, URISyntaxException {
    // need to download the file to simulator in folder
    try {
        JSONObject jsonObject = new JSONObject(message);
        String sasUri = (String) jsonObject.get("fileUrl");
        System.out.println("SAS URI from hub ->" + sasUri + "  ");
        URI url = new URI(sasUri);
        //downloadFile(sasUri);
        System.out.println("end of file download function");
        CloudBlob blob = new CloudBlockBlob(url);
        blob.downloadToFile("/path/to/download/file");
    } catch(Exception e) {
        e.printStackTrace();
    }
}

Below is SAS URI :-

https://*******.blob.core.windows.net/test/testfile.zip?sv=2017-07-29&ss=b&srt=sco&sp=rwdlac&se=2018-04-16T13:33:22Z&st=2018-04-16T05:00:22Z&spr=https&sig=***********

I am getting the SAS URI from azure portal directly , not generating at runtime.

Thanks in advance!

1
You don't need to add Authorization header for a SAS URI as the authorization is included in the URL itself (sig part of the URI). More than likely there's an issue with your SAS URL itself. Can you share the SAS URI and also the code that you're using to generate it. Please edit your question and include these details.Gaurav Mantri

1 Answers

0
votes

To narrow down the issue you can have a try of the following method to see if it helps.

Get the URI of the blob in Azure Portal by click "Download" like this:

enter image description here

After that, the file will be downloaded. You can find the URI in explorer download history. The URI format will like this:

https://[storage-account].blob.core.windows.net/testdownload/20180417_4.zip?sv=2017-07-29&ss=bqtf&srt=sco&sp=rwdlacup&se=2018-04-19T15:52:15Z&sig=[signature]

Directly use this URI in the following code piece and it will work.

            CloudBlob blob = new CloudBlockBlob(url);
            await blob.DownloadToFileAsync(imgPath, System.IO.FileMode.CreateNew);

Upate: Another way to get absolute URI to the blob from Azure Portal looks like this:

First get SAS token. Note the Start and expiry date/time. The token is valid only in this time period.

enter image description here

Second get blob URL.

enter image description here

Finally, the complete absolute URI to the blob is blob URL plus SAS token. It will like this:

https://ritastorageaccount.blob.core.windows.net/?sv=2017-07-29&ss=b&srt=sco&sp=rwdlac&se=2018-04-26T10:01:47Z&st=2018-04-26T02:01:47Z&spr=https&sig=[SIG]