0
votes

I have a Xamarin UWP app built using Azure Mobile Apps and I am trying to upload a BLOB to Azure storage with a SAS token and the .Net Azure Storage client (8.4.0). I am able to generate the SAS token for my container via an Easy API Node function but when I try to use it to upload the file, I get an error "Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature."

Easy API Code: for GetUploadToken

var azure = require('azure-storage');

function generateSasToken(container, blobName, permissions) {
    var connString = "<conn string from azure storage acct>"; // removed for StackOverflow question
    var blobService = azure.createBlobService(connString);

    var currentDate = new Date();
    var startDate = new Date(currentDate);
    startDate.setMinutes(currentDate.getMinutes() - 5);

    console.log("startDate:    " + startDate);

    console.log("current date: " + currentDate);

    var expiryDate = new Date(currentDate);
    expiryDate.setMinutes(currentDate.getMinutes() + 60);

    console.log("expiryDate:   " + expiryDate);    

    permissions = permissions || azure.BlobUtilities.SharedAccessPermissions.READ;

    var sharedAccessPolicy = {
        AccessPolicy: {
            Permissions: permissions,
            Start: startDate,
            Expiry: expiryDate
        }
    };

    var sasToken = blobService.generateSharedAccessSignature(container, blobName, sharedAccessPolicy);

    console.log("SAS Token: " + sasToken);
    return {
        token: sasToken,
        uri: blobService.getUrl(container, blobName, sasToken)
    };
}

module.exports = {
    "post": function (req, res, next) {
        if (req.body.Container) {
           console.log("Container: " + req.body.Container);
           console.log("BlobName:" + req.body.BlobName);
           console.log("Permissions:" + req.body.Permissions);

            // The following values can be used for permissions: 
            // "a" (Add), "r" (Read), "w" (Write), "d" (Delete), "l" (List)
            // Concatenate multiple permissions, such as "rwa" = Read, Write, Add
            var token = generateSasToken(req.body.Container, req.body.BlobName, req.body.Permissions);

            res.status(200).type('application/json').json(token);
        } else {
            res.status(400).type("text/plain").text("Specify a value for 'container");
        }
    }
};

Easy API Output

Container: sketches
BlobName:DSCF3726.JPG
Permissions:rwa
startDate:    Thu Oct 05 2017 14:39:36 GMT+0000 (Coordinated Universal Time)
current date: Thu Oct 05 2017 14:44:36 GMT+0000 (Coordinated Universal Time)
expiryDate:   Thu Oct 05 2017 15:44:36 GMT+0000 (Coordinated Universal Time)
SAS Token: st=2017-10-05T14%3A39%3A36Z&se=2017-10-05T15%3A44%3A36Z&sp=rwa&sv=2017-04-17&sr=b&sig=...

Upload Code

internal async Task<string> UploadAsync(string fileName, byte[] dataArray)
{
    var sketchFile = new SketchFile
    {
        BlobName = fileName,
        Container = "sketches",
        Permissions = "rwa"
    };

    var response = await CurrentClient.InvokeApiAsync<SketchFile, GetSasTokenResponse>(
        "GetUploadToken", 
        sketchFile);

    try
    {
        var blob = new CloudBlockBlob(new Uri(response.Uri));

        await blob.UploadFromByteArrayAsync(dataArray, 0, dataArray.Length);
    }
    catch (StorageException se)
    {
        System.Diagnostics.Debug.WriteLine($"Error uploading {fileName}: {se.RequestInformation.ExtendedErrorInformation.ErrorMessage}.");

        return null;
    }

    var uri = response.Uri.Substring(0, response.Uri.IndexOf('?'));

    return uri;
}
1

1 Answers

1
votes

Based on your code, I could reproduce this issue on my side. I assumed that it may caused by the Permissions you specified. As Permissions for a blob states about the Add permission as follows:

Allowed operations: Add a block to an append blob.

You could use Azure Storage Explorer and generate the sas token for your block blob to narrow this issue.

Per my test, change the Permissions to rw, then I could successfully upload my file to azure blob storage.