Reputation: 1745
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
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
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