Intro

In the previous post I described OperationContext class and provided basic usage examples. In this post I am going to focus on the shared access signature concept.

Prerequisites

Refer to previous posts to get started with Azure Storage Queue Service.

Code

Shared access signature (SAS) provides delegated access to resources in a storage account. It is possible to give specific permissions to specific client for a limited amount of time without having to share access account keys. A shared access signature is a URI that points to one or more storage resources and includes a token that contains a special set of query parameters. The token indicates how the resources may be accessed by the client. There are two types of SAS: account-level SAS and service-level SAS. With service-level SAS you can delegate access to resource in just one of the storage services: blob, queue, table, file. All of the operations available via a service SAS are also available via an account SAS. But with account level SAS you can delegate access to service-level operations. Also, with account SAS it is possible to reference stored access policy for greater flexibility. More information can be found on MSDN.

Consider the following example of the simple service level SAS:

queue.AddMessage(new CloudQueueMessage("sas-test"));
            
var sasToken = queue.GetSharedAccessSignature(new SharedAccessQueuePolicy
{
    SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-15),
    SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(15),
    Permissions = SharedAccessQueuePermissions.ProcessMessages
});

var processingQueue = new Microsoft.WindowsAzure.Storage.Queue.CloudQueue(queue.Uri, new StorageCredentials(sasToken));
var message = processingQueue.GetMessage();
Console.WriteLine(message.AsString);

processingQueue.AddMessage(new CloudQueueMessage("sas-test-add")); // Exception here

This code adds a message to the queue and creates a SAS token, this SAS token then used to create an another instance of CloudQueue. The new instance has permissions to process messages, so it can dequeue the message and then delete it. After 15 minutes it will stop working. It can't add new messages to the queue. That's why AddMessage fails with (403) Forbidden.

But if we change the Permissions property to:

Permissions = SharedAccessQueuePermissions.ProcessMessages | SharedAccessQueuePermissions.Add

Our code will finish the work succesfuly.

There are 5 different SharedAccessQueuePermissions flags that can be used to control the SAS token permission set:

  • None - no shared access granted
  • Read - permission to peek messages and read queue metadata
  • Update - permission to update messages
  • Add - permission to add messages
  • PorocessMessages - permission to get and delete messages from queue.

As you already know they can be combined. Usually there are two sides involved, one adds messages and the other processes them. In this case it is a good idea to give them different permission set, so the processing part won't add more messages to the queue by accident.

Refer to Constructing a Service SAS to find what permissions you need to specify for the specific operation.

The next example demonstrates a simple account-level SAS:

queue.AddMessage(new CloudQueueMessage("sas-test"));
var sasToken = storageAccount.GetSharedAccessSignature(new SharedAccessAccountPolicy()
{
    SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-15),
    SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(15),
    Protocols = SharedAccessProtocol.HttpsOnly,
    ResourceTypes = SharedAccessAccountResourceTypes.Object,
    Services = SharedAccessAccountServices.Queue,
    Permissions = SharedAccessAccountPermissions.ProcessMessages | SharedAccessAccountPermissions.Add
});

var processingQueue = new Microsoft.WindowsAzure.Storage.Queue.CloudQueue(queue.Uri, new StorageCredentials(sasToken));
var message = processingQueue.GetMessage();
Console.WriteLine(message.AsString);
processingQueue.DeleteMessage(message);
processingQueue.AddMessage(new CloudQueueMessage("sas-test-add")); 

This code will be executed with no exceptions. This shared access signature will grant the same level of permissions we used in the previous example but for all queues in the given storage account.

There are 4 resource types that can be combined:

  • None - no shared access granted
  • Service - permission to access service-level API granted
  • Container - permission to access container-level API granted
  • Object - permission to access object-level API granted

You have to specify the correct resource type and the permissions mask to issue desired SAS. Refer to Constructing an Account SAS to find what parameters you need to specify for the specific operation.

Summary

In this post I briefly described shared access signature and provided basic code samples for most common usage scenarios. Delegation is a great concept and SAS is a good implementation of this concept. Stored access policies is another great feature that enables better control over SAS. The next post will be about stored access policies.


;