내보내기(0) 인쇄
모두 확장
EN
이 콘텐츠는 한국어로 제공되지 않아 영어 버전으로 표시됩니다.

Controlling Access to Azure Blob Containers with Java

Updated: April 4, 2014

This guide will show you how to perform common tasks using the Azure Blob storage service. The samples are written in Java and use the Azure SDK for Java. The scenarios covered include uploading, listing, downloading, and deleting blob containers, blobs, and metadata. Access control is fundamental to using cloud storage securely and productively in your Java applications and so samples are presented by the type of access control demonstrated: Public Access, Shared Access Signatures, and Stored Access policy. The samples were all compiled and run as Java applications in Eclipse and using the Azure Plugin for Eclipse with Java (by Microsoft Open Technologies).

After running the samples in the section about public access, you should be able to accomplish the following tasks with Java.

  • Create a storage account connection string to your Azure storage account

  • Create a new blob container in your storage account

  • Adjust the public access anonymous users have to the container metadata, blob content, and blob metadata

  • Add metadata to a blob container in your storage account

  • Upload a blob from your computer into an Azure blob container

  • Add metadata to a blob in your storage account

  • Read container metadata as an anonymous user

  • List all the blobs stored in a container as an anonymous user

  • Read blob metadata as an anonymous user

  • Download a blob from an Azure storage account to your computer as an anonymous user

Your Java application can create a blob container in Azure storage. It can also specify the level of public read access to the blobs and metadata saved in the container. Public access is the level of read permission automatically given an anonymous user that is in possession of the public access url for the container or blob. You cannot use public access to give anonymous users write permissions to the container. If you need to give write permission to users that are not in possession of the account key of your Azure storage account, then you will need to provide those users with a token in the form of a url that references a shared access signature or a shared access policy.

If the public access to the blob container is not currently off (private,) anonymous user will be able to read all blobs in the container using a public access url such as the following.

http://grassy.blob.core.windows.net/container1/image2.jpg

Although public access is turned off by default for a new blob container, if the public access gets turned back on the public access url will give anonymous users read access to the container. Do not try to enable users to read one blob in your container by turning on public access, this will turn on public access for the entire container. A user knowing the public access url for one blob may be able to guess and construct working urls for other blobs in the container. Public access alone is therefore a weak method to use to control access to your blob containers. If you need stronger control over access to blob content and container metadata, then you will need to associate the container with a shared access signature or a shared access policy.

To create a new blob container in your Azure storage account, or to change the level of public access to an existing blob container in your account, you will require the account name and the account key for your Azure storage account. Your will need to use the account name and key to construct a storage connection string. Your application may use Java code similar to the following example to construct and return a storage connection string. The same Account class is used with all the examples in this guide that need to provide the Azure storage account name and account key.

public class Account 
{
   private String storageConnectionString;
   public Account()
   {
   this.storageConnectionString =
      "DefaultEndpointsProtocol=http;" + 
      "AccountName=grassy;" + 
      "AccountKey=nPPnnnnPPPPb5nnPnnn5nn5nPnnPnn50P/nnPnPPnPn+PnPPnP/n2nnPPPPn
          Pn55555PPPPn/P5nnP5P+n5n==";
   }
   public String getstorageconnectionstring()
   {
   return storageConnectionString;
   }
} 

With this storage account string, your application may then use Java code similar to the following to create a new blob container named container1 with public access set to OFF. If container1 already exists, running this code resets the level of public access to OFF. Note that a container name must be in lowercase.

public class MakeContainer
{
public static void main(String[] args) throws InvalidKeyException, URISyntaxException, StorageException 
   {        
   Account creds = new Account(); //Exposes the storage account’s secret key            
   final String storageConnectionString = creds.getstorageconnectionstring();
   CloudStorageAccount storageAccount = 
      CloudStorageAccount.parse(storageConnectionString);
   CloudBlobClient blobClient = storageAccount.createCloudBlobClient();
   CloudBlobContainer container = blobClient.getContainerReference("container1");
   container.createIfNotExist();
   BlobContainerPermissions containerPermissions = 
      new BlobContainerPermissions();
   //All anonymous public access to the container is OFF
   containerPermissions.setPublicAccess(BlobContainerPublicAccessType.OFF);
   container.uploadPermissions(containerPermissions);
   BlobContainerPublicAccessType access1 = 
      containerPermissions.getPublicAccess();
   System.out.println("Public access to " + container.getName() + " is set to: 
      " + access1);
   }
}

With the storage account string, an application can also write metadata in the container in the form of a HashMap<String, String> object. For example, the following Java code adds three items to the container2 metadata.

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("container2");
  container.createIfNotExist();
  HashMap<String, String> meta = new HashMap<String, String>();
  meta.put("city", "San Francisco");
  meta.put("desc", "Photos");
  meta.put("date", "June 2012");
  container.setMetadata(meta);
  container.uploadMetadata();   
  System.out.println("Container metadata was added to " + container.getName());
  }

Public access for container1 has been turned off by setting the value of the publicAccess property to the appropriate constant of the BlobContainerPublicAccessType enum -OFF. The value of the publicAccess property can be one of the following three constants which specify the level of public read access.

  • BLOB – The public can read the content and metadata of blobs within this container, but cannot read container metadata or list the blobs within the container.

  • CONTAINER – The public can read blob content and metadata and container metadata, and can list the blobs within the container.

  • OFF – Specifies no public access. Only the account owner can read resources in this container.

You cannot give anonymous users write permission using public access. However, you can give an anonymous user read permission to blob content, blob metadata, and container metadata using public access. If public access for container2 has been set to CONTAINER, the following Java code enables an anonymous user to read the container metadata. Note that you must call downloadAttributes() on the container object to read the container metadata.

public static void main(String[] args) throws InvalidKeyException, 
   URISyntaxException, StorageException 
   { 
   //Get a reference to the blob container   
   //This does not expose the storage account’s secret key         
   URI baseuri = new URI("http://grassy.blob.core.windows.net");
   CloudBlobClient blobclient = new CloudBlobClient(baseuri);
   CloudBlobContainer container = blobclient.getContainerReference("container2");
   container.downloadAttributes();  //Must be called before reading metadata
   HashMap<String, String> meta = container.getMetadata();
   System.out.println(container.getName() + " contains this metadata." );
   System.out.println(meta.get("city"));
   System.out.println(meta.get("desc"));
   System.out.println(meta.get("date"));
   }


Remember that the public access determines the public read access for the entire container, and if your application turns on public access to enable one blob to be read, it may become possible for the public to list and to read all blobs in the container. For example, the following Java code uploads the blob image4.jpg into container1 and changes the level of public access from OFF to CONTAINER. Finally, the code adds some metadata to go with the blob image4.jpg. The file image4.jpg is initially stored locally on the account owner’s computer.

public static void main(String[] args) throws InvalidKeyException, 
   URISyntaxException, StorageException, FileNotFoundException, IOException         
   {
   Account creds = new Account();            
   final String storageConnectionString = creds.getstorageconnectionstring();  
   CloudStorageAccount account = 
      CloudStorageAccount.parse(storageConnectionString);
   CloudBlobClient serviceClient = account.createCloudBlobClient();
   CloudBlobContainer container = 
      serviceClient.getContainerReference("container1");
   container.createIfNotExist();
   BlobContainerPermissions containerPermissions;
   containerPermissions = new BlobContainerPermissions();
   //Anonymous users can list blobs and read blobs and metadata
   containerPermissions.setPublicAccess(BlobContainerPublicAccessType.CONTAINER);
   container.uploadPermissions(containerPermissions);
   CloudBlockBlob blob = container.getBlockBlobReference("image4.jpg");
   //Local source file will be uploaded to blob-container in cloud   
   File fileReference = new File ("c:\\myimages\\image4.jpg");
   blob.upload(new FileInputStream(fileReference), fileReference.length());
   BlobContainerPublicAccessType access1 = 
      containerPermissions.getPublicAccess();
   System.out.println("Public access to " 
      + container.getName() + " is set to: " + access1);
   }                

A public access of CONTAINER enables anonymous users to access to all the blobs in the container, but also gives anonymous users permission to list all the blobs in the container and read any other blobs that exist in that container. The following code enables an anonymous user to list the blobs.

public static void main(String[] args) throws InvalidKeyException, 
   URISyntaxException, StorageException, FileNotFoundException, IOException 
   {        
   URI baseuri = new URI("http://grassy.blob.core.windows.net");
   CloudBlobClient blobclient = new CloudBlobClient(baseuri);
   CloudBlobContainer container = blobclient.getContainerReference("container1");   
   for (ListBlobItem blobItem : container.listBlobs()){
      System.out.println(blobItem.getUri());}
   }

Because public access is CONTAINER for container1, an anonymous user can read the metadata and content of all blobs in the container using Java code such as the following. Note that you must first call downloadAttributes() on the blob object to read blob metadata.

public static void main(String[] args) throws InvalidKeyException, 
   URISyntaxException, StorageException, FileNotFoundException, IOException 
   {        
   URI baseuri = new URI("http://grassy.blob.core.windows.net");
   CloudBlobClient blobclient = new CloudBlobClient(baseuri);
   CloudBlobContainer container = blobclient.getContainerReference("container1");
   CloudBlockBlob blob = container.getBlockBlobReference("image4.jpg"); 
   blob.downloadAttributes();  // Required to read metadata
   HashMap<String, String> user = new HashMap<String, String>();    
   user = blob.getMetadata();    
   String name = (user.get("firstname") + " " + user.get("lastname"));
   String age = ("age: " + user.get("age"));
   String present = ("Presenting talk? " + user.get("presenter"));
   System.out.println(name);
   System.out.println(age);
   System.out.println(present);
   String blobName = "image4.jpg";
   //Image in cloud blob container will be downloaded to local file  
   String localFileName = "c:\\myoutputimages\\image4.jpg";  
   File fileTarget = new File(localFileName); 
   blob.download(new FileOutputStream(fileTarget));
   System.out.println("The blob at:\n"  + baseuri +  "/" + container.getName() 
      + "/" + blobName + "\nwas downloaded from the cloud to local file:\n" 
      + localFileName); 
   }  

Although public access control of blob containers is relatively easy to use, you will also need to implement shared access signatures or shared access policies if your Java application needs to do any of the following.

  • Give access to selected non-owners of the storage account without exposing access to all anonymous users.

  • Enable non-owners of the storage account temporary write access, as well as read access, to blob containers.

  • Limit access by non-owners of the storage account to short specified periods of time.

  • Grant temporary access to a container and then be able to revoke access without having to delete the container or change storage account key.

After running the samples in the section about shared access signatures, you should be able to accomplish the following tasks with Java.

  • Generate a shared access signature (SAS) that gives temporary container access to one or more SAS users

  • Distribute different access permissions to different users without extending access to all anonymous users

  • Extend temporary read, write, list, or delete access to one blob container but no other containers

  • Access a private container (public access off) without knowledge of the Azure storage account key

  • Download a blob from a private blob container using a basic SAS

  • Upload a blob into a private blob container using a basic SAS

  • List or delete any blobs in a private container but no other container

  • Read and write container and blob metadata

A shared access signature (SAS) contains all the information necessary to give any user controlled access to blobs saved in an Azure blob container. A basic SAS is not associated with a shared access policy and will provide irrevocable access to any user in possession of the SAS for a limited time. A basic SAS has an expiration time which cannot be extended. Once a SAS has been distributed, it cannot be cancelled, access to the container can only be revoked prior to the expiration time by changing the Azure storage account key.

An application in possession of the Azure storage key can generate a basic SAS for controlling access to a blob container saved in the storage account by specifying one or more of the following constants in the SharedAccessBlobPermissions enum of a SharedAccessBlobPolicy object. Note that a SAS controls access at the container level and gives the same access to all the blobs in the container

  • READ - Read the content, properties, metadata or block list of any blob in the container. Use any blob in the container as the source of a copy operation.

  • WRITE - For any blob in the container, create or write content, properties, metadata, or block list. Snapshot or lease the blob. Resize the blob (page blob only). Note: You cannot grant permissions to read or write to container properties or metadata.

  • DELETE- Delete any blob in the container. Note: You cannot grant permissions to delete an entire container.

  • LIST - List blobs in the container.

For example, the following string represents a basic SAS containing all the information necessary to access the container.

sp=rwdl&sr=c&sv=2012-02-12&se=2013-03-27T20%3A20%3A21Z&st=2013-03-27T19%3A20%3A21Z&sig=nn5PPPnnPPnPPnnPP%5PPPnnP55P5nnPP5nPn%5P5nnPPn5%5P

The SAS can be appended to the public access url for the blob as query parameters to construct a SAS url. Because the SAS contains all the necessary information, any user in possession of this url has access. Note that to construct a working url, a query symbol (?) is required between the public access url and SAS.

http://grassy.blob.core.windows.net/container1/image3.jpg?sp=rwdl&sr=c&sv=2012-02-12&se=2013-03-27T20%3A20%3A21Z&st=2013-03-27T19%3A20%3A21Z&sig=nn5PPPnnPPnPPnnPP%5PPPnnP55P5nnPP5nPn%5P5nnPPn5%5P

Once this url is distributed it cannot be cancelled or extended beyond the expiration time. It can give any application that obtains it read, write, list, and delete access to the blobs in the container. It stops working after the expiration time and cannot be reactivated.

The following Java code creates a blob container named container1 if it does not already exist. It sets the public access level of container1 to OFF. It generates a basic SAS string with an applicable time span of 1 hour. You may specify a time span longer than 1 hour. The period of applicability starts immediately and expires one hour later. During the applicable time span, any user in possession of the SAS has READ, WRITE, DELETE, and LIST access permissions for the container. Rerunning this code a second time before the first expiration time does not revoke the permissions conveyed by the first SAS and urls based on the old SAS will continue to work. After the expiration time, a url appended with the expired SAS will not work. If this code is rerun after the expiration time, it generates a new valid SAS which can give permissions for another hour, but the old SAS is not reactivated. At all times anonymous user access to the container is controlled by the specified public access level.

public class BasicSAS 
{
   public static void main(String[] args) throws InvalidKeyException, 
      URISyntaxException, StorageException 
   {
   Account creds = new Account();  //Account key required to create SAS             
   final String storageConnectionString = creds.getstorageconnectionstring();
   CloudStorageAccount storageAccount = 
      CloudStorageAccount.parse(storageConnectionString);
   CloudBlobClient blobClient = storageAccount.createCloudBlobClient();
   CloudBlobContainer container = blobClient.getContainerReference("container1");
   container.createIfNotExist();
   SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy();
   GregorianCalendar calendar = 
      new GregorianCalendar(TimeZone.getTimeZone("UTC"));
   calendar.setTime(new Date());
   policy.setSharedAccessStartTime(calendar.getTime());  //Immediately applicable
   calendar.add(Calendar.HOUR, 1); //Applicable time span is 1 hour
   policy.setSharedAccessExpiryTime(calendar.getTime());
   policy.setPermissions(EnumSet.of(SharedAccessBlobPermissions.READ, 
      SharedAccessBlobPermissions.WRITE, SharedAccessBlobPermissions.DELETE,
      SharedAccessBlobPermissions.LIST));  // SAS grants all access privileges
   BlobContainerPermissions containerPermissions = 
      new BlobContainerPermissions();
   //Private blob-container with no access for anonymous users
   containerPermissions.setPublicAccess(BlobContainerPublicAccessType.OFF);
   container.uploadPermissions(containerPermissions);
   String sas = container.generateSharedAccessSignature(policy,null);           
   System.out.println("The basic shared access signature :");
   System.out.println(sas);
   }
}

During the one hour time span of SAS applicability, an application in possession of the SAS url for the blob container can write a blob in container1 using Java code similar to the following. Recall that anonymous users (public access) cannot be given write permission to blob containers. Finally, some information about the author of the image is written as metadata saved with the blob. The SAS does not enable write access to the container metadata.

The following Java code enables a user in possession of the SAS to write a blob without knowledge of the Azure storage account key.

public class SASblober 
{
   public static void main(String[] args) throws URISyntaxException, 
      FileNotFoundException, StorageException, IOException 
   {
   //This does not reveal the secret storage account key
   URI baseuri = new URI("http://grassy.blob.core.windows.net");
   CloudBlobClient blobclient = new CloudBlobClient(baseuri);
   MyUploadBlob("container1",
      "sp=rwdl&sr=c&sv=2012-02-12&se=2013-03-27T20%3A20%3A21Z&st=2013-03- 
      27T19%3A20%3A21Z&sig=nn5PPPnnPPnPPnnPP%5PPPnnP55
      P5nnPP5nPn%5P5nnPPn5%5P",
      blobclient);
   }

   public static void MyUploadBlob(String containerName, String containerSAS, 
      CloudBlobClient blobClient) throws URISyntaxException, StorageException, 
      FileNotFoundException, IOException
   {
   //Uploads a local file to blob-container in cloud
   String blobName = "image3.jpg";  
   String localFileName = "c:\\myimages\\image3.jpg";  
   URI uri = new URI(blobClient.getEndpoint().toString() + "/" +
      containerName + "/" + 
      blobName + 
      "?" + 
      containerSAS);
   CloudBlockBlob sasBlob = new CloudBlockBlob(uri, blobClient);
   HashMap<String, String> user = new HashMap<String, String>();    
   user.put("firstname", "Joe");
   user.put("lastname", "Brown" );
   user.put("age", "28");
   user.put("presenter", "no");  
   sasBlob.setMetadata(user);
   File fileReference = new File(localFileName);
   sasBlob.upload(new FileInputStream(fileReference), fileReference.length());
   System.out.println("The blob: " + blobName + " has been uploaded to:");
   System.out.println(uri);
   }
}

Because READ is included with the permissions associated with the example SAS, an application in possession of the SAS url can read a blob in container1 and then write the contents into a local file using Java code similar to the following and without knowledge of the Azure storage account key. Finally, the code reads and displays metadata that was stored with the blob.

public class SASread 
{
   public static void main(String[] args) throws URISyntaxException, 
      FileNotFoundException, StorageException, IOException 
   {
   URI baseuri = new URI("http://grassy.blob.core.windows.net");
   CloudBlobClient blobclient = new CloudBlobClient(baseuri);
   MyDownloadBlob("container1",
      "sp=rwdl&sr=c&sv=2012-02-12&se=2013-03-27T20%3A20%3A21Z&st=2013-03- 
       27T19%3A20%3A21Z&sig=nn5PPPnnPPnPPnnPP%5PPPnnP55P5nnPP5nPn%5P5nnPPn5%5P",
       blobclient);
}

   public static void MyDownloadBlob(String containerName, String containerSAS, 
      CloudBlobClient blobClient) throws URISyntaxException, StorageException, 
      FileNotFoundException, IOException
   {
   //Downloads blob in cloud to local file
   String blobName = "image3.jpg";  
   String localFileName = "c:\\myoutputimages\\image3.jpg";  
   URI uri = new URI(blobClient.getEndpoint().toString() + "/" + containerName 
      + "/" + blobName + "?" + containerSAS);   
   CloudBlockBlob sasBlob = new CloudBlockBlob(uri, blobClient);
   File fileTarget = new File(localFileName); 
   sasBlob.download(new FileOutputStream(fileTarget));   
   HashMap<String, String> user = new HashMap<String, String>();    
   user = sasBlob.getMetadata();    
   String name = (user.get("firstname") + " " + user.get("lastname"));
   String age = ("age: " + user.get("age"));
   String present = ("Presenting talk? " + user.get("presenter"));
   System.out.println(name);
   System.out.println(age);
   System.out.println(present);
   System.out.println("The blob at:\n"  + uri 
      + "\nwas downloaded from the cloud to local file:\n" + localFileName);
   }
}

Recall that anonymous users cannot list the blobs in container1 if the public access has been set to OFF. Because LIST was included with the permissions associated with the SAS, a user in possession of the SAS url can use the following Java code to list the blobs in the container without knowledge of the Azure storage account key.

public class Listblobs 
{
   public static void main(String[] args) throws 
      URISyntaxException,StorageException
   {
   URI baseuri = new URI("http://grassy.blob.core.windows.net");
   CloudBlobClient serviceclient = new CloudBlobClient(baseuri);
   MyList("container1",
      "sp=rwdl&sr=c&sv=2012-02-12&se=2013-03-27T20%3A20%3A21Z&st=2013-03- 
      27T19%3A20%3A21Z&sig=nn5PPPnnPPnPPnnPP%5PPPnnP55P5nnPP5nPn%5P5nnPPn5%5P",
      serviceclient);
   }

   public static void MyList(String containerName, String containerSAS, 
      CloudBlobClient serviceClient) throws URISyntaxException, StorageException 
   {
   URI uri = new URI(serviceClient.getEndpoint().toString() + "/" 
      + containerName + "?" + containerSAS);
   CloudBlobContainer container = new CloudBlobContainer(uri, serviceClient);
      for (ListBlobItem blobItem : container.listBlobs()) 
      {
      System.out.println(blobItem.getUri());
      }
   }  
}   

Because DELETE is included with the permissions associated with the SAS, a user in possession of the SAS url can delete blobs in container1. Note that you cannot grant a user permission to delete the blob container from the storage account. During the time span of SAS applicability, the following Java code deletes an existing blob in container.

public class SASDelete 
{
   public static void main(String[] args) throws URISyntaxException, 
      FileNotFoundException, StorageException, IOException 
   {
   URI baseuri = new URI("http://grassy.blob.core.windows.net");
   CloudBlobClient blobclient = new CloudBlobClient(baseuri);
   MyDeleteBlob("container1",
      "sp=rwdl&sr=c&sv=2012-02-12&se=2013-03-27T20%3A20%3A21Z&st=2013-03- 
      27T19%3A20%3A21Z&sig=nn5PPPnnPPnPPnnPP%5PPPnnP55P5nnPP5nPn%5P5nnPPn5%5P",
      blobclient);
   }
   public static void MyDeleteBlob(String containerName, String containerSAS, 
      CloudBlobClient serviceClient) throws URISyntaxException, 
      FileNotFoundException, IOException, StorageException
   {
   String blobName = "image4.jpg";  
   URI uri = new URI(serviceClient.getEndpoint().toString() + "/" +
      containerName + "/" + blobName + "?" + containerSAS);
   CloudBlockBlob sasBlob = new CloudBlockBlob(uri, serviceClient);
   try {sasBlob.delete();
      System.out.println(blobName + " was deleted");} 
   catch (StorageException storageException){
      System.out.println(storageException.getMessage());
      System.exit(-1);}
   } 
}

Follow these best practices when using shared access signatures (SAS) to ensure that access is restricted as much as possible both in access permissions and also the applicable time span. Remember that while public access merely allows read access to containers and blobs, shared access signatures can give write and delete access to your cloud-based resources. If the SAS url is leaked to unintended users, this can lead to the destruction of resources stored in your storage account.

  • Shared access signatures should always be constructed with the least rights necessary. That is, if only READ access is necessary, do not distribute a SAS which also grants LIST, WRITE, and DELETE privileges.

  • If a shared access signature has rights that are not intended for the general public, distribute the SAS to intended users by HTTPS because HTTP requests would disclose the full SAS url over the internet.

  • Because a basic SAS cannot be revoked, always take the added step to generate a SAS associated with a container-level stored access policy. A SAS that is created with a stored access policy can be revoked prior to the expiration time without having to change your Azure account key.

After running the samples in the section about stored access policy, you should be able to accomplish the following tasks with Java.

  • Generate a policy SAS that gives container access that can be revoked, extended, or updated

  • Cancel all container urls after distribution without changing your Azure storage key

  • Reactivate a policy SAS after its expiration time

  • Revoke or update urls based on a policy SAS at any time and change the behavior of old urls

  • Create multiple policies for a single container

  • Use policy SAS and basic SAS together for maximum flexibility of container-level access control

Your application can have greater container-level access control by using a policy SAS rather than a basic SAS. A basic SAS has a limited time span of applicability and cannot be extended or cancelled once it has been distributed. A policy SAS can be specified to remain valid for any length of time and can be cancelled or modified at any time. Because the policy is saved with the container rather than the SAS url, the policy can be updated without having to change the SAS string (or the urls distributed to users.) When the policy for the container is updated, all old urls that have been constructed using the policy SAS are reactivated with the updated policy.

The following Java code creates a blob container1 with a policy named heath if container1 does not already exist. This code sets the public access level of container1 to OFF. It generates a policy SAS string with an applicable time span of 3 hours. The period of applicability starts immediately and expires three hours later. During the applicable time span, any user in possession of the policy SAS has READ, WRITE, DELETE, and LIST access to the container. After the expiration time, a url appended with the expired SAS will not work until it is reactivated by the storage account’s owner using the storage account key. At all times anonymous user access to the container is controlled by the public access level.

If container1 exists, this code adds the policy heath to the container. A blob container can have can have no more than four simultaneous stored access policies. Code showing how to assign multiple stored access policies to a container is shown later. Because a basic SAS saves all its information in the SAS string and a policy SAS saves its information with the container, the access rights of unexpired basic SAS urls are unaffected by adding or modifying a policy SAS. You cannot revoke a basic SAS that has already been distributed by creating a policy SAS for the container.

To revoke and cancel all the urls that have been distributed with the heath policy SAS, rerun the code with an expiration time that is earlier than start time. For example, substitute the following to revoke the policy SAS and cancel all the permissions to urls that have been distributed to users.

policy.setSharedAccessStartTime(calendar.getTime());
calendar.add(Calendar.HOUR, -1); //Expiration time is earlier than start time
policy.setSharedAccessExpiryTime(calendar.getTime());

You can also revoke a policy SAS after distribution by removing or replacing the policy in the container. If the code is rerun on container1, with the name of the policy changed from heath to baxter, the new policy baxter overwrites the old policy heath. This cancels all the urls already distributed with a heath policy SAS. However, the old urls associated with heath policy can be reactivated by rerunning the code a third time with the policy changed from baxter to heath (which cancels all the baxter urls.)

If the following Java code is rerun before or after the expiration time of the policy SAS, this will renew the heath policy SAS for an additional 3 hours and reactivate any revoked or expired heath urls that have been distributed. You can also update the permissions (i.e. add or remove access permissions) at any time by editing and rerunning this code.

public class PolicySAS
{
  public static void main(String[] args) throws InvalidKeyException, 
     URISyntaxException, StorageException 
  {
  Account creds = new Account(); //Account key required to create SAS           
  final String storageConnectionString = creds.getstorageconnectionstring();
  CloudStorageAccount storageAccount = 
     CloudStorageAccount.parse(storageConnectionString);
  CloudBlobClient blobClient = storageAccount.createCloudBlobClient();
  CloudBlobContainer container = blobClient.getContainerReference("container1");
  container.createIfNotExist();
  SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy();
  GregorianCalendar calendar = 
     new GregorianCalendar(TimeZone.getTimeZone("UTC"));
  calendar.setTime(new Date());
  policy.setSharedAccessStartTime(calendar.getTime()); //Immediately applicable
  calendar.add(Calendar.HOUR, 3); //Applicable time-span is 3 hours
  policy.setSharedAccessExpiryTime(calendar.getTime());      
  policy.setPermissions(EnumSet.of(SharedAccessBlobPermissions.READ, 
     SharedAccessBlobPermissions.WRITE, SharedAccessBlobPermissions.DELETE, 
     SharedAccessBlobPermissions.LIST));
  BlobContainerPermissions containerPermissions = new BlobContainerPermissions();
  //Private container with no access for anonymous users
  containerPermissions.setPublicAccess(BlobContainerPublicAccessType.OFF);
  //Name the shared access policy: heath
  containerPermissions.getSharedAccessPolicies().put("heath", policy);
  container.uploadPermissions(containerPermissions);
  //Generate the policy SAS string for heath access
  String sas = container.generateSharedAccessSignature(
     new SharedAccessBlobPolicy(),"heath");           
  System.out.println("The stored access policy signature:");
  System.out.println(sas);
  }        
}

The policy SAS can be appended to the basic url for the blob as query parameters to construct a decorated url with the controlled permissions in the same way as a basic SAS. Note that the SAS generated by the code above does not include the query symbol (?) required between the basic url and policy SAS. For example, the string for blob image3.jpg would be similar to the following.

http://grassy.blob.core.windows.net/container1/image3.jpg?sr=c&sv=2012-02-12&sig=nnPn5P5nnPPnn5Pnn5PPnPPPnPPP5PPPPPP%5PPnn5PPn%55&si=heath

Applications can use the policy SAS in exactly the same way as a basic SAS. Simply substitute the policy SAS string for the basic SAS string in the previous examples to use shared access policy to control access at the container-level. Applications that have a policy SAS can perform read, write, list, or delete operations on blobs in the container without knowledge of the Azure storage account key.

A useful pattern to implement flexible container-level access control is to specify four stored access policies for the container that respectively give read, write, list, and delete access. This approach still leaves the ability to also distribute as necessary short-lived basic SAS urls for the container. The basic SAS urls can give access permissions independent of the policy. The following Java code demonstrates how four stored access policies can be saved for a single container.

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("container1");
   container.createIfNotExist();            
   BlobContainerPermissions containerPermissions = 
      new BlobContainerPermissions();
   containerPermissions.setPublicAccess(BlobContainerPublicAccessType.OFF);            
   SharedAccessBlobPolicy read = new SharedAccessBlobPolicy();
   SharedAccessBlobPolicy write = new SharedAccessBlobPolicy();
   SharedAccessBlobPolicy list = new SharedAccessBlobPolicy();
   SharedAccessBlobPolicy delete = new SharedAccessBlobPolicy();
   GregorianCalendar calendar = 
      new GregorianCalendar(TimeZone.getTimeZone("UTC"));
   SharedAccessBlobPolicy[] policies = new SharedAccessBlobPolicy[]{
      read, write, list, delete};
   calendar.setTime(new Date());            
   for(SharedAccessBlobPolicy policy : policies){
      policy.setSharedAccessStartTime(calendar.getTime());}            
   calendar.add(Calendar.HOUR, 1);
   for(SharedAccessBlobPolicy policy : policies){
      policy.setSharedAccessExpiryTime(calendar.getTime());}
   read.setPermissions(EnumSet.of(SharedAccessBlobPermissions.READ));
   write.setPermissions(EnumSet.of(SharedAccessBlobPermissions.WRITE));
   list.setPermissions(EnumSet.of(SharedAccessBlobPermissions.LIST));
   delete.setPermissions(EnumSet.of(SharedAccessBlobPermissions.READ, 
      SharedAccessBlobPermissions.DELETE));     
   containerPermissions.getSharedAccessPolicies().put("r", read );
   containerPermissions.getSharedAccessPolicies().put("w", write);
   containerPermissions.getSharedAccessPolicies().put("l", list);
   containerPermissions.getSharedAccessPolicies().put("d", delete);
   container.uploadPermissions(containerPermissions);
   String[] pr = new String[]{"r", "w", "l", "d"};
      for(String p : pr){System.out.println(
      container.generateSharedAccessSignature(new SharedAccessBlobPolicy(),p));}        
   }

During the applicable time span of the policy SAS, any application in possession of the policy SAS and the basic url for the blob container can use the permissions that have been associated with the heath stored access policy. Your application can use the policy SAS in exactly the same way as a basic SAS. Simply substitute the policy SAS string for the basic SAS string in the previously provided examples to have your application control container-level access to container1 using the heath policy.

See Also

Microsoft는 MSDN 웹 사이트에 대한 귀하의 의견을 이해하기 위해 온라인 설문 조사를 진행하고 있습니다. 참여하도록 선택하시면 MSDN 웹 사이트에서 나가실 때 온라인 설문 조사가 표시됩니다.

참여하시겠습니까?
표시:
© 2014 Microsoft