1
votes

Good day everybody, I'm stuck with authorization on azure storage. When I am uploading only one file(blob) I put SAS key in the url and everything works fine. But when I need to create chunks in BLOB service, there must be Authorization header(Amazon says that) when creating them. I am trying to use this article to create authorization.

There is my JavaScript code(I use ng-file-uploader library):

    $scope.upload = function (file) {
    blockId = blockId + 1;
    Upload.upload({
        url: "https://MYSTORAGENAME.blob.core.windows.net/kont1/"+ file.name + "?comp=block&blockid=" + blockId,
        method: 'PUT',
        resumeChunkSize: '40MB', // upload in chunks of specified size
        headers: {
            'Content-type': 'multipart/form-data',
            'Authorization': 'SharedKey' + "MYSTORAGENAME:iDrJ7OuggJ8uoIn5olNDeOvSAoMrpqckl5mUaT5/H/w=",
            'x-ms-version': '2015-12-11',
            'x-ms-date': new Date().toUTCString()
            },
        data: {file: file}
    }).then(function (resp) {
        console.log('Success ' + resp.config.data.file.name + 'uploaded. Response: ' + resp.data);
    }, function (resp) {
        console.log('Error status: ' + resp.status);
    }, function (evt) {
        var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
        console.log('progress: ' + progressPercentage + '% ' + evt.config.data.file.name);
    });
};

This request returns: 400 (Authentication information is not given in the correct format. Check the value of Authorization header.)

When I try to change this: 'Authorization': 'SharedKey' + "MYSTORAGENAME:iDrJ7OuggJ8uoIn5olNDeOvSAoMrpqckl5mUaT5/H/w="

to this: 'Authorization': "SharedKey sand2storage:iDrJ7OuggJ8uoIn5olNDeOvSAoMrpqckl5mUaT5/H/w="

Then it returns: 403 (Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.)

I spent 2days on this and still can't get it right, maybe somebody see's what I am missing? Thank you in advance.

NOTE:

iDrJ7OuggJ8uoIn5olNDeOvSAoMrpqckl5mUaT5/H/w=

I generate this key in Azure page each try to make it sure that key is correct.

Image when generating key from Azure site

1
Could you please share how are you calculating the SharedKey value?Aaron Chen
I just take the sig value from generated "Shared access signature ". Look at the picture I inserted at the end of the question.Shpooke
Also I tried to generate it using azure node library : var blobSvc = azure.createBlobService("STORAGE_NAME","ACCESS_KEY","STORAGE_NAME.blob.core.windows.net"); var startDate = new Date(); var expiryDate = new Date(startDate); expiryDate.setMinutes(startDate.getMinutes() + 800); var ap = { AccessPolicy: { Permissions: azure.BlobUtilities.SharedAccessPermissions.WRITE, Start: startDate, Expiry: expiryDate }, }; var token = blobSvc.generateSharedAccessSignature('CONTAINER_NAME', 'myblob', ap);Shpooke
About how to generate shared key please refer to this post: Authentication for the Azure Storage ServicesAaron Chen
Thanks for help. But even if I generated the key I still was getting the same error. Gaurav Mantri solution worked for me in many ways. As I experienced, the problem could be that I was free trial user.Shpooke

1 Answers

4
votes

If you're using Shared Access Signature (SAS), then you don't need to specify the Authorization header as the SAS token contains this value. You also need not define x-ms-version and x-ms-date headers. What you do need to include is x-ms-blob-type request header and set its value to BlockBlob.

What you would need to do is take the SAS token and append that to your URL (please make sure that you don't include the ? in the SAS Token.

Assuming you're storing the Sas Token from portal in a variable called sasToken, your code would be:

$scope.upload = function (file) {
    blockId = blockId + 1;
    Upload.upload({
        url: "https://MYSTORAGENAME.blob.core.windows.net/kont1/"+ file.name + "?comp=block&blockid=" + blockId + "&" + sasToken,
        method: 'PUT',
        resumeChunkSize: '40MB', // upload in chunks of specified size
        headers: {
            'Content-type': 'multipart/form-data',
            'Authorization': 'SharedKey' + "MYSTORAGENAME:iDrJ7OuggJ8uoIn5olNDeOvSAoMrpqckl5mUaT5/H/w=",
            'x-ms-version': '2015-12-11',
            'x-ms-date': new Date().toUTCString()
            },
        data: {file: file}
    }).then(function (resp) {
        console.log('Success ' + resp.config.data.file.name + 'uploaded. Response: ' + resp.data);
    }, function (resp) {
        console.log('Error status: ' + resp.status);
    }, function (evt) {
        var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
        console.log('progress: ' + progressPercentage + '% ' + evt.config.data.file.name);
    });
};