Granting container access using Shared Access Policy
-
07 Ekim 2010 Perşembe 14:46
Hello,
I have a scenario where I need different business partners (hundreds) to upload files into Azure through BLOB storage service. Obviously I don't want to share my key.
It's also impossible to provide a SAS to a BLOB; since they might overwrite files (or wait till my worker role reads and deletes the file), which I don't want to have.
One possible solution is create containers for each partner, create Shared Access Policy for each of them, and provide a SAS "for container", which they can use to upload files with different file names.
But when I tried this, it fails saying "Authentication headers are incorrect". Looks like we can't use SAS at "container" level for BLOB operations. Steve Marx (http://blog.smarx.com/posts/using-container-level-access-policies-in-windows-azure-storage) mentioned something similar in his blog.
So is it impossible to create a SAS for a container (based on a Shared Access Policy of that container) and provide it to an external party to blob operations?
Thanks in advance!
-hantaana
Tüm Yanıtlar
-
07 Ekim 2010 Perşembe 16:25
Hi,
Please take a look at this thread where Neil talked about uploading a blob using SAS:
Hope this helps.
Thanks
Gaurav Mantri
Cerebrata Software
-
07 Ekim 2010 Perşembe 16:46
Hi Gaurav,
Thanks for the response. However this doesn't address my problem. If I'm to implement a solution according to above thread; I have to have another custom service which issues SAS for the new BLOB.
Client will call my custom service by passing the name of the blob it wants to create, service will reply with SAS and client will use that to upload the file.
regards
hantaana
-
07 Ekim 2010 Perşembe 16:48
You can indeed use a container-level access policy to let people upload blobs.
What did you try that didn't work? (Can you share some code?)
-
07 Ekim 2010 Perşembe 16:51Yanıtlayıcı
An issue here is that Put Blob is a repeatable operation so someone with a write shared access signature can repeatedly upload the blob until the shared access signature becomes invalid. The thing about shared access signatures is that you need to generate a valid signature and share it with your clients. Then you need to provide them some way of uploading the files using the signature. Shared access signatures can be useful but you might want to think about how they would be used in your application.
Following on from the link in Gaurav's post the following code shows how simple it is to provide a shared access signature for a container and then upload an arbitrary blob using the signature. (yikes).
static public void WriteBlobWithSharedAccessSignatureForContainer(CloudBlobClient cloudBlobClient, String containerName, String blobName) { CloudBlobContainer cloudBlobContainer = new CloudBlobContainer(containerName, cloudBlobClient); SharedAccessPolicy sharedAccessPolicy = new SharedAccessPolicy(); sharedAccessPolicy.Permissions = SharedAccessPermissions.Write; sharedAccessPolicy.SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-10); sharedAccessPolicy.SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(40); String sharedAccessSignature = cloudBlobContainer.GetSharedAccessSignature(sharedAccessPolicy); String absoluteUri = String.Format("{0}{1}/{2}{3}", AzureStorageConstants.BlobEndPoint, containerName, blobName, sharedAccessSignature); CloudBlockBlob cloudBlockBlob = new CloudBlockBlob(absoluteUri); cloudBlockBlob.UploadText("The Bright Side of the Road"); }
-
07 Ekim 2010 Perşembe 19:24
Thanks for all responses.
Neil: I need to issue SAS based on a policy "on a container"; in this way I have control over the signature I issued. But I got the essense from your code on how you try to solve the issue.
Steve: You are correct. Why it didn't work for me? Because I was defining time period twice. First when creating the Shared Access Policy, secondly when creating the SAS based in that policy. Error I was getting is "Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature."
I got around it by defining time only in policy and passing an empty SharedAccessPolicy when creating the signature. It worked!!!! Find code below.
Server side code [or I would use some tool to do the same]
CloudStorageAccount cloudStorageAccount1 = CloudStorageAccount.FromConfigurationSetting("DiagnosticsConnectionString");
CloudBlobClient cloudBlobClient = cloudStorageAccount1.CreateCloudBlobClient();
CloudBlobContainer cloudBlobContainer = cloudBlobClient.GetContainerReference("salesdata");
cloudBlobContainer.CreateIfNotExist();
SharedAccessPolicy sap = new SharedAccessPolicy();
sap.Permissions = SharedAccessPermissions.Read | SharedAccessPermissions.Write;
sap.SharedAccessStartTime = DateTime.UtcNow;
sap.SharedAccessExpiryTime = DateTime.UtcNow + TimeSpan.FromDays(100);
BlobContainerPermissions bcp = new BlobContainerPermissions();
bcp.PublicAccess = BlobContainerPublicAccessType.Off;
bcp.SharedAccessPolicies.Clear();
bcp.SharedAccessPolicies.Add("partneraccess", sap);
cloudBlobContainer.SetPermissions(bcp);
var sas = cloudBlobContainer.GetSharedAccessSignature(new SharedAccessPolicy()
{}, "partneraccess");
The SAS should be then passed to the client.
Client side code [or I would use some tool to do the same]
var sasCreds = new StorageCredentialsSharedAccessSignature(sas);
var sasBlob = new CloudBlobClient(strBlobEndpoint, sasCreds).GetBlobReference("salesdata/"+ Guid.NewGuid().ToString());
sasBlob.UploadText("sales data from business partner1");
- Yanıt Olarak İşaretleyen hantaana 08 Ekim 2010 Cuma 14:01