Using a container-level access policy
A shared access policy comprises a set of permissions (read, write, delete, list) combined with start and expiration times for validity of the policy. There are no restrictions on the start and expiration times for a shared access policy. A container-level access policy is a shared access policy associated by name with a container. A maximum of five container-level access policies can be associated simultaneously with a container, but each must have a distinct name.
A container-level access policy improves the management of shared access signatures. There is no way to retract or otherwise disallow a standalone shared access signature once it has been created. However, a shared access signature created from a container-level access policy has validity dependent on the container-level access policy. The deletion of a container-level access policy causes the revocation of all shared access signatures derived from it and they can no longer be used to authenticate a storage request. As they can be revoked at any time, there are no time restrictions on the validity of a shared access signature derived from a container-level access policy.
The container-level access policies for a container are set and retrieved as a SharedAccessPolicies
collection of named SharedAccessPolicy
objects. The SetPermissions()
and GetPermissions()
methods of the CloudBlobContainer
class set and retrieve container-level access policies. A container-level access policy can be removed by retrieving the current SharedAccessPolicies
, removing the specified policy, and then setting the SharedAccessPolicies
on the container again.
A shared access signature is derived from a container-level access policy by invoking the CloudBlobContainer.GetSharedAccessSignature()
passing in the name of the container-level access policy and an empty SharedAccessPolicy
instance. It is not possible to modify the validity of the shared-access signature by using a non-empty SharedAccessPolicy
.
In this recipe, we will learn how to manage container-level access policies and use them to create shared access signatures.
Getting ready
This recipe assumes the following is in the application configuration file:
<appSettings> <add key="DataConnectionString"value="DefaultEndpointsProtocol=https;AccountName={ACCOUNT_NAME};AccountKey={ACCOUNT_KEY}"/> </appSettings>
We must replace {ACCOUNT_NAME}
and {ACCOUNT_KEY}
with appropriate values for the account name and access key.
How to do it...
We are going to create, use, modify, revoke, and delete a container-level access policy. We do this as follows:
Add a class named
ContainerLevelAccessPolicyExample
to the project.Add the following
using
statements to the top of the class file:using Microsoft.WindowsAzure; using Microsoft.WindowsAzure.StorageClient; using System.Configuration;
Add the following private members to the class:
private Uri blobEndpoint; private CloudBlobContainer cloudBlobContainer;
Add the following constructor to the class:
ContainerLevelAccessPolicyExample() { CloudStorageAccount cloudStorageAccount =CloudStorageAccount.Parse(ConfigurationManager.AppSettings["DataConnectionString"]); blobEndpoint = cloudStorageAccount.BlobEndpoint; CloudBlobClient cloudBlobClient =cloudStorageAccount.CreateCloudBlobClient(); cloudBlobContainer =new CloudBlobContainer(containerName, cloudBlobClient); cloudBlobContainer.Create(); }
Add the following method, creating a container-level access policy, to the class:
private void AddContainerLevelAccessPolicy(String policyId) { DateTime startTime = DateTime.UtcNow; SharedAccessPolicy sharedAccessPolicy =new SharedAccessPolicy() { Permissions = SharedAccessPermissions.Read |SharedAccessPermissions.Write, SharedAccessStartTime = startTime, SharedAccessExpiryTime = startTime.AddDays(3d) }; BlobContainerPermissions blobContainerPermissions =new BlobContainerPermissions(); blobContainerPermissions.SharedAccessPolicies.Add(policyId, sharedAccessPolicy); blobContainer.SetPermissions(blobContainerPermissions); }
Add the following method, getting a shared access signature using the container-level access policy, to the class:
private String GetSharedAccessSignature(String policyId) { SharedAccessPolicy sharedAccessPolicy =new SharedAccessPolicy(); String sharedAccessSignature =cloudBlobContainer.GetSharedAccessSignature(sharedAccessPolicy, policyId); return sharedAccessSignature; }
Add the following method, modifying the container-level access policy, to the class:
private void ModifyContainerLevelAccessPolicy(String policyId) { BlobContainerPermissions blobContainerPermissions =cloudBlobContainer.GetPermissions(); DateTime sharedAccessExpiryTime =(DateTime)blobContainerPermissions.SharedAccessPolicies[policyId].SharedAccessExpiryTime; blobContainerPermissions.SharedAccessPolicies[policyId].SharedAccessExpiryTime = sharedAccessExpiryTime.AddDays(1d); blobContainer.SetPermissions(blobContainerPermissions); }
Add the following method, revoking a container-level access policy, to the class:
private void RevokeContainerLevelAccessPolicy(String policyId) { BlobContainerPermissions containerPermissions =cloudBlobContainer.GetPermissions(); SharedAccessPolicy sharedAccessPolicy =containerPermissions.SharedAccessPolicies[policyId]; containerPermissions.SharedAccessPolicies.Remove(policyId); containerPermissions.SharedAccessPolicies.Add(policyId + "1", sharedAccessPolicy); cloudBlobContainer.SetPermissions(containerPermissions); }
Add the following method, deleting all container-level access policies, to the class:
private void DeleteContainerLevelAccessPolicies() { BlobContainerPermissions blobContainerPermissions =new BlobContainerPermissions(); blobContainer.SetPermissions(blobContainerPermissions); }
Add the following method, using the methods added earlier, to the class:
public static void UseContainerLevelAccessPolicyExample() { String containerName = "{CONTAINER_NAME}";String policyId = "{POLICY_NAME}"; ContainerLevelAccessPolicyExample example =new ContainerLevelAccessPolicyExample(containerName); example.AddContainerLevelAccessPolicy(policyId); String sharedAccessSignature1 =example.GetSharedAccessSignature(policyId); example.ModifyContainerLevelAccessPolicy(policyId); String sharedAccessSignature2 =example.GetSharedAccessSignature(policyId); example.RevokeContainerLevelAccessPolicy(policyId); String sharedAccessSignature3 =example.GetSharedAccessSignature(policyId + "1"); example.DeleteContainerLevelAccessPolicies(); }
How it works...
In steps 1 and 2, we set up the class. In step 3, we add some private members which we initialize in the constructor we add in step 4. We also create a container in the constructor.
In step 5, we create a SharedAccessPolicy
instance and add it to the SharedAccessPolicies
property of a BlobContainerPermissions
object. Finally, we pass this and a policy name into a SetPermissions()
method of the CloudBlobContainer
class to create a container-level access policy name for the container.
In step 6, we get a shared access signature for a container with a specified container-level access policy. We initialize a CloudStorageAccount
from the application configuration and use this to get a CloudBlobContainer
instance for a specified container. Finally, we pass the policy name into the CloudBlobContainer.GetSharedAccessSignature()
method to get a shared access signature for the container.
In step 7, we again get a CloudBlobContainer
instance for the container and invoke GetPermissions()
on it to retrieve the shared access policies for the container. We then add one day to the expiration date for a specified container-level access policy. Finally, we invoke CloudBlobContainer.SetPermissions()
to update the container-level access policies for the container.
In step 8, we revoke an existing container-level access policy and create a new container-level policy with the same SharedAccessPolicy
and a new policy name. We again use GetPermissions()
to retrieve the shared access policies for the container and then invoke the Remove()
and Add()
methods of the SharedAccessPolicies
class to perform the revocation. Finally, we invoke CloudBlobContainer.SetPermissions()
to update the container-level access policies for the container.
In step 9, we delete all container-level access policies for a container. We create a default BlobContainerPermissions
instance and pass this into CloudBlobContainer.SetPermissions()
to remove all the container-level access policies for the container.
In step 10, we add a helper method that invokes all the methods we added earlier. We need to replace {CONTAINER_NAME}
and {POLICY_NAME}
with the names of a container and a policy for it.