January 7, 2012

Shared Access Signature

A “Shared Access Signature” (SAS) is a set of URL query parameters that represents all information necessary to grant controlled access to a Windows Azure blob or container resource.  The below diagram shows how a URL for accessing a secured blob resource looks like:



Given below a sample URL with shared access signature components:





The components   of “Shared Access Signature” or the URL query parameters representing “Shared Access Signature” are:

No:

Query Parameters
1
The interval over which the signature is valid:

Start time
st
End time
se
2
The resource
sr
3
The permissions associated with the signature
sp
4
The signature
sig
5
Identifier for the policy associated with the container
si

Table 1

Note: You might have noticed that the sample URL does not include query option si  (item 5 in the above Table1), this is an optional field and it’s associated with the “container-level access policy” which allows additional measure of control over Shared Access Signatures. I will explain how to use it in the section "Container Level Access Policy".

1.     The Signature (sig):

 This section shows how to construct a signature string for a Shared Access Signature, which is represented by the sig query option (item 4 in Table1).





Here’s the code where we construct signature using C#:

              string azureStorageSharedKey = "" // Your Storage Account key Here
        string permissions = "r";
        DateTime startTime = DateTime.Now;
        DateTime expiryTime = startTime.AddMinutes(60);
        string canonicalPathToResource = "/anuchandy/ebooks";
        string policyIdentifer = String.Empty;
        byte[] keyForSigning = Convert.FromBase64String(azureStorageSharedKey);
        string signature = null;

        string stringtosign = permissions + "\n" +
               startTime.ToUniversalTime().ToString("yyyy-MM-ddThh:mm:ssZ") + "\n" +
               expiryTime.ToUniversalTime().ToString("yyyy-MM-ddThh:mm:ssZ") + "\n" +
               canonicalPathToResource + "\n" +
               policyIdentifer;
               
        using (var hmac = new HMACSHA256(keyForSigning))
        {
            signature = Convert.ToBase64String(
               hmac.ComputeHash(Encoding.UTF8.GetBytes(stringtosign))
            );
        }

The following section describes the components which made up the “String to Sign”

1.1 Permission(s) [Permissions]

The permissions component of the “string to sign” indicates which operations are permitted on the secured resource (resource can be either a blob in the container or a container itself) which is going to be accessed using the Shared Access Signature. The resource is identified by the “CanonicalPathToResourcecomponent of “string to sign”.
        In the above C# code the canonical path to resource is "/anuchandy/ebooks" which represents the container. “/anuchandy/ebooks/pgmingAzure.pdf" represents canonical path to a blob resource. If the “CanonicalPathToResourceidentify the container, then the shared access signature can be used to perform the operations identified by “permissions” component on all the blobs under the container.
Supported permissions include read (r), write (w), delete (d), and list (l).
Permissions may be grouped so as to allow multiple operations, for example to grant read-write permissions we can use rw.
Note: The permissions should be in the following order: rwdl. Any combination of these permissions is acceptable, so long as they are in the specified order. For example rw is valid but wr is invalid.

1.2  Start-Time [UTC_StartTime_In_ yyyy-MM-ddThh:mm:ssZ_Format]

The time at which the Shared Access Signature becomes valid. The time must be UTC times and adhere to YYYY-MM-DDThh:mm:ssZ ISO 8061 format.

1.3  Expiry-Time [UTC_ExpiryTime_In_ yyyy-MM-ddThh:mm:ssZ_Format]

The time at which the Shared Access Signature becomes invalid. The time must be UTC times and adhere to YYYY-MM-DDThh:mm:ssZ ISO 8061 format.

1.4  CanonicalPathToResource [canonical path_to_resource]

The Shared Access Signature can be used to access two types of resources:
  • ·         A container
  • ·         A blob in the container
This component represents canonical path to the above types of reources. The formats of this component are:
  • ·         /<account name>/<container name> è container resource
             e.g. “/anuchandy/ebooks" represents canonical path to container resource.
  • ·         /<account name>/<container name>/<blob name> è blob resource.     
       e.g. /anuchandy/ebooks/pgmingAzure.pdf" represents canonical path to a blob resource.


1.5  Policy Identifier [Policy_identifier]

This is an optional component and it’s associated with the “container-level access policy” which allows additional measure of control over Shared Access Signatures. I will explain about this component later, for the timing we will keep the value of this component as empty string.

2.     The Resource (sr):


This (item 2 of Table 1) query parameter represents the type of resource needs to be accessible via the Shared Access Signature.  (b for blob and c for container).

3.     The Start-Time (st):


This (item 1.a of Table 1) query parameter represents the time at which the Shared Access Signature becomes valid. The time m ust be UTC times and adhere to YYYY-MM-DDThh:mm:ssZ ISO 8061 format.

4.     The Expiry-Time (se):


This (item 1.b of Table 1) query parameter represents the time at which the Shared Access Signature becomes invalid. The time must be UTC times and adhere to YYYY-MM-DDThh:mm:ssZ ISO 8061 format.


Putting all together: Creating Shared Access Signature (SAS)

Now we are aware of the query parameters that make up the SAS, we can form the SAS as follows:

string sharedAccessSignature = string.Format("st={0}&se={1}&sr=c&sp=r&sig={2}",
     Uri.EscapeDataString(startTime.ToUniversalTime().ToString("yyyy-MM-ddThh:mm:ssZ")),
     Uri.EscapeDataString(expiryTime.ToUniversalTime().ToString("yyyy-MM-ddThh:mm:ssZ")),
     Uri.EscapeDataString(signature));

signature” is the signature from code we used to construct signature.
The generated “sharedAccessSignature” looks like:

st=2012-01-07T10%3A15%3A08Z&se=2012-01-07T11%3A15%3A08Z&sr=b&sp=r&sig=sv%2BSQIofAcDd8KFrIsK5xtRkfxsBkK8vTUUkuwR6ymc%3D


Now we can use this SAS to access the blob resource as follows:

http://anuchandy.blob.core.windows.net/ebooks/pgmingAzure.pdf? st=2012-01-07T10%3A15%3A08Z&se=2012-01-07T11%3A15%3A08Z&sr=b&sp=r&sig=sv%2BSQIofAcDd8KFrIsK5xtRkfxsBkK8vTUUkuwR6ymc%3D


Life Time of Shared Access Signature
We used the starTime and expiryTime components of “signature (sig)” to define lifetime of SAS. Another component that affect SAS lifetime is “Policy Identifier”, for generating the “signature (sig)” component of SAS we used empty value for “Policy Identifier”
string policyIdentifer = String.Empty;

“Policy Identifier” links the SAS with “container level access policy” defined for your container.  If the SAS is not linked with “container level access policy” (i.e. with empty “Policy Identifier” in signature) then the maximum life time we can define for SAS is 1 Hour.
If a start time is specified, the expiration time must be 60 or fewer minutes from the start time, or the signature is invalid and cannot be used. If no start time is specified, the signature is valid only during the 60 minute period before the expiration time.
So if we define the following time interval:
        DateTime startTime = DateTime.Now;
        DateTime expiryTime = startTime.AddMinutes(65);

Then you will not be able to access the resource using the generated SAS.


Container Level Access Policy

yet to come....

1 comment: