How do I create a multiple retention policy for a single Azure Container Container?

Ive read and played with the sample code at https://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-shared-access-signature-part-2/#part-1-create-a-console -application-to-generate-shared-access-signatures

Then I applied it to my script.

I am writing a tool to load data from a partner into Azure blob storage and then it will be used by some internal commands: YYYY-MM (container) (DD-GUID) (prefix) File1.zip File2.zip ......

I have created 2 policies for each container: 1. Write for partner only so they can only write blobs and nothing else. 2. List and read for our internal teams so they can list and read (download) all the drops in the container.

My thought is that I can just pass the correct policy to the correct recipients; however my implementation does not work as I expected.

I created 2 policies for each container using the method below, with the correct policy permission of course:

static void CreateSharedAccessPolicy(CloudBlobClient blobClient, CloudBlobContainer container, string policyName)
    {
        //Create a new stored access policy and define its constraints.
        SharedAccessBlobPolicy sharedPolicy = new SharedAccessBlobPolicy()
        {
            SharedAccessExpiryTime = DateTime.UtcNow.AddHours(10),
            Permissions = SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.List
        };

        //Get the container existing permissions.
        BlobContainerPermissions permissions = new BlobContainerPermissions();

        //Add the new policy to the container permissions.
        permissions.SharedAccessPolicies.Clear();
        permissions.SharedAccessPolicies.Add(policyName, sharedPolicy);
        container.SetPermissions(permissions);
    }

      

I first created a write-only policy and then a read and list policy. I noticed that the first policy doesn't seem to work, everything returned 403 Forbidden and for the second policy, the only thing that works is List blob but not Read (I tried to load the blob but got 404 Not Found).

It seems I've missed something very basic here. Could you please help me figure out what's wrong with my approach?

The code I used to check container permissions also notice that read permission on container doesn't really work as mentioned somewhere in the Azure documentation. Here I am trying to find an easy way to just give people a saved access policy so they can display and load all blobs in the container instead of giving them the signature in the blob file:

static void UseContainerSAS (sas string) {// Try to do container operations with the provided SAS.

        //Return a reference to the container using the SAS URI.
        CloudBlobContainer container = new CloudBlobContainer(new Uri(sas));

        //Create a list to store blob URIs returned by a listing operation on the container.
        List<Uri> blobUris = new List<Uri>();

        try
        {
            //Write operation: write a new blob to the container. 
            CloudBlockBlob blob = container.GetBlockBlobReference("blobCreatedViaSAS.txt");
            string blobContent = "This blob was created with a shared access signature granting write permissions to the container. ";
            MemoryStream msWrite = new MemoryStream(Encoding.UTF8.GetBytes(blobContent));
            msWrite.Position = 0;
            using (msWrite)
            {
                blob.UploadFromStream(msWrite);
            }
            Console.WriteLine("Write operation succeeded for SAS " + sas);
            Console.WriteLine();
        }
        catch (StorageException e)
        {
            Console.WriteLine("Write operation failed for SAS " + sas);
            Console.WriteLine("Additional error information: " + e.Message);
            Console.WriteLine();
        }

        try
        {
            //List operation: List the blobs in the container, including the one just added.
            foreach (ICloudBlob blobListing in container.ListBlobs())
            {
                blobUris.Add(blobListing.Uri);
            }
            Console.WriteLine("List operation succeeded for SAS " + sas);
            Console.WriteLine();
        }
        catch (StorageException e)
        {
            Console.WriteLine("List operation failed for SAS " + sas);
            Console.WriteLine("Additional error information: " + e.Message);
            Console.WriteLine();
        }

        try
        {
            CloudBlockBlob blob = container.GetBlockBlobReference(blobUris[0].ToString());

            MemoryStream msRead = new MemoryStream();
            msRead.Position = 0;
            using (msRead)
            {
                blob.DownloadToStream(msRead);
                Console.WriteLine(msRead.Length);
            }
            Console.WriteLine("Read operation succeeded for SAS " + sas);
            Console.WriteLine();
        }
        catch (StorageException e)
        {
            Console.WriteLine("Read operation failed for SAS " + sas);
            Console.WriteLine("Additional error information: " + e.Message);
            Console.WriteLine();
        }
        Console.WriteLine();

        try
        {
            //Delete operation: Delete a blob in the container.
            CloudBlockBlob blob = container.GetBlockBlobReference(blobUris[0].ToString());
            blob.Delete();
            Console.WriteLine("Delete operation succeeded for SAS " + sas);
            Console.WriteLine();
        }
        catch (StorageException e)
        {
            Console.WriteLine("Delete operation failed for SAS " + sas);
            Console.WriteLine("Additional error information: " + e.Message);
            Console.WriteLine();
        }
    }

      

+3


source to share


1 answer


Actually, your last operation deleted what you did in the first operation. To avoid this, you must read the existing container permissions, add a new permission, and then set the permissions back to the container.

Below is the correct example code:

static void CreateSharedAccessPolicy(CloudBlobClient blobClient, CloudBlobContainer container, string policyName)
{
    //Create a new stored access policy and define its constraints.
    SharedAccessBlobPolicy sharedPolicy = new SharedAccessBlobPolicy()
    {
        SharedAccessExpiryTime = DateTime.UtcNow.AddHours(10),
        Permissions = SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.List
    };

    //Get the container existing permissions.
    BlobContainerPermissions permissions = container.GetPermissions();

    //Add the new policy to the container permissions.
    permissions.SharedAccessPolicies.Add(policyName, sharedPolicy);
    container.SetPermissions(permissions);
}

      



Due to the fact that you are facing a 404 error for reading blobs, please provide the code for creating SAS according to rules and how you use the generated SAS for reading blobs so that I can help solve the problem.

Below is some sample code to create SAS and use it to read blob: (you can copy + paste urls to stdout into browser directly to try)

        var permissions = container.GetPermissions();
        var policy = new SharedAccessBlobPolicy
        {
            Permissions = SharedAccessBlobPermissions.Read,
            SharedAccessExpiryTime = DateTime.UtcNow.AddYears(1),
        };

        string policyName = "read";
        permissions.SharedAccessPolicies.Add(policyName, policy);
        container.SetPermissions(permissions);
        string sas = container.GetSharedAccessSignature(null, policyName);
        var blobs = container.ListBlobs(null, true);
        Console.WriteLine("SAS = {0}", sas);
        Console.WriteLine("Blobs URLs with SAS:");

        foreach (var blob in blobs)
        {
            Console.WriteLine(blob.Uri.ToString() + sas);
        }

      

+7


source







All Articles