404 error for Shared Access Signature with v2 of Azure Storage Client Library
azure, azure-blob-storage, azure-storage, c#
Solution
When initializing the `CloudBlobClient` you need to pass 2 parameters
- baseUri: Blob url without SAS, `http://test.blob.core.windows.net/temp/Imports/2012-12-01_20-56-52.zip`
- credentials: This should be your SAS without the url, `?sv=2012-02-12&se=2012-12-01T21%3A57%3A56Z&sr=b&sp=rw&sig=5JboXXM1Yeo%2BuI6mb18VbURluo%3D`
Working sample:
var blobClient = new CloudBlobClient(new Uri(blob.Uri.AbsoluteUri), new StorageCredentials(sharedAccesSignature));
using (var fileStream = File.OpenRead(fileFullPath))
{
blobClient.GetBlobReferenceFromServer(new Uri(blob.Uri.AbsoluteUri))
.UploadFromStream(fileStream);
}
Extra tip: You don't need to get a reference to the container. You can immediately access the blob by calling `GetBlobReferenceFromServer` on the `CloudBlobClient`.
Problem
I'm trying to generate a Shared Access Signature for a blob (and use it) with the v2.0 of the Windows Azure Storage Client Library. I started with this sample but it's for v1.7, and transposing it to 2.0 gives a 404 error. Here is my actual code : Server side, to generate the SAS : ``` var myAccount = CloudStorageAccount.Parse( ConfigurationManager.ConnectionStrings[ "AzureStorageConnectionString"].ConnectionString); var myContainer = myAccount.CreateCloudBlobClient() .GetContainerReference(containerName); myContainer.CreateIfNotExists(); string blobName = "Imports/" + DateTime.UtcNow.ToString("yyyy-MM-dd_HH-mm-ss") + ".zip"; var myBlob = myContainer.GetBlockBlobReference(blobName); using (var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes("Hey, I'm empty for now."))) { myBlob.UploadFromStream(stream); } var sharedAccesSignature = myBlob.GetSharedAccessSignature( new Microsoft.WindowsAzure.Storage.Blob.SharedAccessBlobPolicy() { Permissions = Microsoft.WindowsAzure.Storage.Blob.SharedAccessBlobPermissions.Write | Microsoft.WindowsAzure.Storage.Blob.SharedAccessBlobPermissions.Read, SharedAccessExpiryTime = DateTime.UtcNow.AddHours(1), }); return myBlob.Uri.AbsoluteUri + sharedAccesSignature; ``` It tried many things at client side, resulting sometimes in 404, or 403 server error. For exemple I tried this (result : 404) : ``` var blobClient = new CloudBlobClient(new Uri(blobWithSharedAccessSignature)); // blobWithSharedAccessSignature here is : https://azertyuiop.blob.core.windows.net/container1/Imports/2012-12-01_19-43-54.zip?sv=2012-02-12&se=2012-12-01T20%3A43%3A54Z&sr=b&sp=rw&sig=h0bTUk[...]3D // calling blobWithSharedAccessSignature from a webBrowser works. // result here is valid for containerName : container1 var container = blobClient.GetContainerReference(containerName); ICloudBlob blobRef = container.GetBlobReferenceFromServer(blobWithSharedAccessSignature); ==> error 404 using (var fileStream = File.OpenRead(fileFullPath)) { blobRef.UploadFromStream(fileStream); } ``` I tried replacing ``` container.GetBlobReferenceFromServer(blobWithSharedAccessSignature); ``` by ``` container.GetBlockBlobReference(blobWithSharedAccessSignature); ``` I also tried replacing ``` blobClient = new CloudBlobClient(new Uri(blobWithSharedAccessSignature)); ``` by ``` blobClient = new CloudBlobClient(new Uri(blobWithSharedAccessSignature), new StorageCredentials(blobWithSharedAccessSignature)); ``` which results in a "403 - forbidden" error. Can someone help me by giving a full sample in v2 ? Or tell me were's my mistake ? Thanks ! UPDATE - solution here : (thanks to Sandrino Di Mattia) ``` // Assuming that blobWithSharedAccessSignature is : // "https://azertyuiop.blob.core.windows.net/container1/Imports/2012-12-01_19-43-54.zip?sv=2012-02-12&se=2012-12-01T20%3A43%3A54Z&sr=b&sp=rw&sig=h0bTUkTR%2FdTF%2BVZgDUuBPHqG%2BiTtFeXK4kepBpDR2AU%3D" Uri blobUriWithoutCredentials = new Uri(new Uri(blobWithSharedAccessSignature).GetLeftPart(UriPartial.Path)); // here blobUriWithoutCredentials is https://azertyuiop.blob.core.windows.net/container1/Imports/2012-12-01_19-43-54.zip string credentials = blobWithSharedAccessSignature.Substring(blobWithSharedAccessSignature.IndexOf('?')); // here credentials is "?sv=2012-02-12&se=2012-12-01T22%3A26%3A55Z&sr=b&sp=rw&sig=Lsk8kLyJ8TFoGNVLbFLftCIXUNlIIRPZalkhoPdUfh8%3D" var blobClient = new CloudBlobClient(blobUriWithoutCredentials, new StorageCredentials(credentials)); ICloudBlob blobRef = blobClient.GetBlobReferenceFromServer(blobUriWithoutCredentials); using (var fileStream = File.OpenRead(fileFullPath)) { blobRef.UploadFromStream(fileStream); } ```