user1790300
user1790300

Reputation: 1745

403 Error when testing azure Blob Storage upload

I read and implemented the following article for chunking files between javascript client and azure blob storage: http://gauravmantri.com/2013/02/16/uploading-large-files-in-windows-azure-blob-storage-using-shared-access-signature-html-and-javascript. I seem to be able to generate the Shared Access Signature and create the permissions, but when I try to "PUT" the chunks up to azure with the following SAS URL, I am receiving the error: "403 (Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.)". Could someone please what I am doing wrong. Here is the code and url and code:

//sas url that is generated
http://testing.blob.core.windows.net/image-container?sr=c&si=Perms1&sig=UowbDVCLfFdiVktTZuoupj6BiMUzLRxF3WEZlXKMJcA%3D&comp=block&blockid=YmxvY2stMDAwMDAw


//Upload the blocks to azure storage
if (evt.target.readyState == FileReader.DONE) { // DONE == 2
    var uri = submitUri + '&comp=block&blockid=' + blockIds[blockIds.length - 1];
    var requestData = new Uint8Array(evt.target.result);
    $.ajax({
        url: uri,
        type: "PUT",
        data: requestData,
        processData: false,
        beforeSend: function(xhr) {
            xhr.setRequestHeader('x-ms-blob-type', 'BlockBlob');
            //xhr.setRequestHeader('Content-Length', requestData.length);
        },
        success: function (data, status) {
            console.log(data);
            console.log(status);
            bytesUploaded += requestData.length;
            var percentComplete = ((parseFloat(bytesUploaded) / parseFloat(selectedFile.size)) * 100).toFixed(2);
            $("#fileUploadProgress").text(percentComplete + " %");
            uploadFileInBlocks();
        },
        error: function(xhr, desc, err) {
            console.log(desc);
            console.log(err);
        }
    });
}


         //Create stored access permissions
         Microsoft.WindowsAzure.Storage.Blob.CloudBlobClient blobClient = _storageAccount.CreateCloudBlobClient();

        //Get a reference to a container to use for the sample code, and create it if it does not exist.
        Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer container = blobClient.GetContainerReference("images-container");
        container.CreateIfNotExists();

        //Create a new stored access policy and define its constraints.
        Microsoft.WindowsAzure.Storage.Blob.SharedAccessBlobPolicy sharedPolicy = new Microsoft.WindowsAzure.Storage.Blob.SharedAccessBlobPolicy()
        {
            SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(10),
            Permissions = Microsoft.WindowsAzure.Storage.Blob.SharedAccessBlobPermissions.Write
        };

        //Get the container's existing permissions.
        Microsoft.WindowsAzure.Storage.Blob.BlobContainerPermissions permissions = container.GetPermissions();

        //Add the new policy to the container's permissions.
         if (!permissions.SharedAccessPolicies.ContainsKey(CloudConfiguration.GetConfigurationSetting("PolicyName")))
        {
            permissions.SharedAccessPolicies.Clear();
            permissions.SharedAccessPolicies.Add(policyName, sharedPolicy);
            container.SetPermissions(permissions);
        }


        //Generate the SAS Locator
       CreateStoredAccessPolicy(CloudConfiguration.GetConfigurationSetting("PolicyName"));

        //Create the blob client object.
        Microsoft.WindowsAzure.StorageClient.CloudBlobClient blobClient = _storageAccount.CreateCloudBlobClient();

        //Get a reference to a container to use for the sample code, and create it if it does not exist.
        Microsoft.WindowsAzure.StorageClient.CloudBlobContainer container = blobClient.GetContainerReference("images-container");

        //Set the expiry time and permissions for the container.
        //In this case no start time is specified, so the shared access signature becomes valid immediately.
        SharedAccessPolicy sasConstraints = new SharedAccessPolicy();

        //Generate the shared access signature on the container, setting the constraints directly on the signature.
        string sasContainerToken = container.GetSharedAccessSignature(sasConstraints, CloudConfiguration.GetConfigurationSetting("PolicyName"));

        var newFileFile = Guid.NewGuid().ToString() + extension;
        var blobUri = new UriBuilder(container.AbsoluteUri.ToString() + sasContainerToken);

        // return the new VideoAsset 
        return new ImageAsset() { SasLocator = blobUri.AbsoluteUri.ToString(), NewFileName = newFileFile };

I am currently testing in debug mode from the azure emulator on my local machine. Not sure if this is a factor.

Upvotes: 0

Views: 3249

Answers (2)

Veena Udayabhanu - MSFT
Veena Udayabhanu - MSFT

Reputation: 1269

When you establish a stored access policy on a container, it may take up to 30 seconds to take effect. During this interval, a shared access signature that is associated with the stored access policy will fail with status code 403 (Forbidden), until the access policy becomes active. For more information on Shared Access policies, please take a look at - https://msdn.microsoft.com/library/azure/dd179391.aspx.

So along with ensuring that you are generating the right URL as mentioned above, please make sure that you wait for 30 seconds before using the policy.

Upvotes: 1

Serdar Ozler
Serdar Ozler

Reputation: 3802

The URL generated points to a container even though you are trying to upload a block. It should also contain a blob name like http://testing.blob.core.windows.net/image-container/image-blob instead.

Upvotes: 0

Related Questions