I am trying to design a Java application running on a local server that manages the access permissions to blobs that are being stored in Windows Azure. The cloud storage resources are used by several mobile applications (also written in Java) that need read access, and sometimes temporary write access, to a single blob container hosted in the cloud. I am using the Windows Azure Plugin for Eclipse with Java by Microsoft Open Technologies.
My question is: How (or if) container-level stored access policies in Azure can be made to revert to an earlier stored policy (READ) on expiration, rather than to “no access. “
The MSDN article: Creating a Shared Access Signature in Java provides a good start, but it doesn’t yet say much about how to use container-level stored policies to manage shared access polies with Java . I am learning Java and SAS, and because I was unable to find Java code examples similar to Access Control for Azure Blobs, I have included a short piece of Java code below to demonstrate my question.
The server application retrieves the private storage connection string used to connect to Azure storage. Gets the cloud storage account and creates a cloud blob client. Gets a reference to the container and creates a container if it does not already exist. (Note that a container name must be lower case.) It then downloads the current permissions for the container. (Up to five container-level stored access policies may be saved for a container.)
For example, let's say there are two stored access policies, named "baxter" and "heath," controlling the container-level permissions, and that both policies were set to READ (only) when the stored access polices of the container were previously saved. These initial policies, with READ permissions, are set to expire after several months. Mobile applications assigned to either the "heath" or "baxter" policies then start out with read-access to blobs stored in sascontainer6 through uri strings similar to:
http://grassy.blob.core.windows.net/sascontainer6/image4.jpg?sr=c&sv=2012-02-12&sig=5G7EOgiYYNEGmw2Y0T4IUgt%2FzTnmYpaxWfB5nEira08%3D&si=baxter
http://grassy.blob.core.windows.net/sascontainer6/image4.jpg?sr=c&sv=2012-02- 12&sig=llUoAg2PvFUfhO28ncrlheh2RRJdb7smQEX6nO8xoCk%3D&si=heath
As needed, the server application can elevate a subset of mobile applications to both READ and WRITE permissions without having to issue a new string. It can do so by modifying the "baxter" policy saved with the container. The ‘granularity’ of the control is at the policy level, and the policy update enables all the mobile applications assigned to the "baxter” policy to write (or overwrite) blobs in the container. Mobile applications assigned to the "heath" policy continue to have READ (only) permission. In a similar way, the server application could revoke all access to the container for applications assigned to a particular policy.
Before changing the policy, the server application ensures that public access to the container has been turned OFF. It specifies the current time as the start time and an expiration time for access that is one hour after the start time. It sets both the READ and WRITE permissions for the new policy. Finally, the existing "baxter" policy is overwritten with the new policy.
The generateSharedAccessSignature method can get a shared access signature (SAS) for the "baxter" and "heath" policies. Changing the permissions saved in the policy should not alter the SAS, and applications using the above uri strings should work until the specified expiration time.
However, once the expiration time is reached, the “baxter” string will lose all permissions to the container, both READ and WRITE. But this is not what I want to happen. I need the permissions for mobile applications assigned to the “baxter” policy to revert back to READ (only.) Because a SAS string with WRITE access enables anyone to write to the resource, the best practice is to keep the period between start time and expiration time as short as possible, no more than an hour. Setting the permissions to READ for longer periods is acceptable for my particular application.
My question is: How (or if) container-level shared access policies in Azure can be used to allow the token (i.e. the “baxter” string shown above) to revert back to an alternate policy (i.e. READ) rather than “no access.”
public static void main(String[] args) throws InvalidKeyException, URISyntaxException, StorageException
{
Account creds = new Account();
final String storageConnectionString = creds.getstorageconnectionstring();
CloudStorageAccount storageAccount = CloudStorageAccount.parse(storageConnectionString);
CloudBlobClient blobClient = storageAccount.createCloudBlobClient();
CloudBlobContainer container = blobClient.getContainerReference("sascontainer6");
container.createIfNotExist();
BlobContainerPermissions containerPermissions = container.downloadPermissions();
containerPermissions.setPublicAccess(BlobContainerPublicAccessType.OFF);
SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy();
GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
calendar.setTime(new Date());
policy.setSharedAccessStartTime(calendar.getTime());
calendar.add(Calendar.HOUR, 1);
policy.setSharedAccessExpiryTime(calendar.getTime());
policy.setPermissions(EnumSet.of(SharedAccessBlobPermissions.READ, SharedAccessBlobPermissions.WRITE));
containerPermissions.getSharedAccessPolicies().put("baxter", policy);
container.uploadPermissions(containerPermissions);
String sas = container.generateSharedAccessSignature(new SharedAccessBlobPolicy(),"baxter");
String sasex = container.generateSharedAccessSignature(new SharedAccessBlobPolicy(),"heath");
}