How to Serve Azure Storage Resources with Grant Limited Access using SAS?

Hüseyin Akdoğan
4 min readJul 31, 2021
https://mostafaelmasry.com

After the decision to use Azure Cloud Storage for the shared resources at the project I was involved in, by reviewing the SDK, I explored how clients can have limited access to resources. We develop the project with Spring Boot and during my research, I found that the resources are not up-to-date for the current Java SDK and Spring Boot version and the tutorials/examples contain many ceremonies and boilerplates.

I wrote this article to share my experience and show how to use Azure Storage Blob SDK with more concise and readable code.

What is Azure Blob Storage?

Azure Blob Storage is Microsoft’s object storage solution that allows you to store a massive amount of unstructured data. Azure Storage Service is a good solution for needs such as streaming video and audio, serving images or documents directly to a browser, etc, as they are accessible using REST APIs.

How to Access Blobs and Serve with Spring Boot?

Since the target audience of this article is users with the service, I will not talk about some prerequisites such as how to create an Azure Storage account and blob containers, etc. In addition, we usually write the access URLs of the stored resources to the database in production but to avoid complexity, I will not include these steps in my example.

As a first step, let’s examine the dependencies we will add to our project to configure and manage the Azure Blob service.

Dependencies

<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>azure-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>azure-spring-boot-starter-storage</artifactId>
</dependency>

The first artifact is for Spring Boot Starters of Azure services and helps Spring Boot developers to adopt Azure services. It supports Spring Boot 2.1.x, 2.2.x, and 2.3.x.

The second provides a starter to auto-configure Azure Blob Storage in your Spring project and allows you to interact with Azure Blob Storage using Spring programming model.

Configuration

The azure-spring-boot-starter-storage dependency requires us to provide values of storage account name and key. In addition to these two values, since we will be using the storage blob resources, we will also provide the endpoint value, which is optional, and connection string value, to be able to inject it at runtime when creating a blob client. You can be found the account key and connection string under Azure Portal ==> Storage Account page ==> Access keys and blob service endpoint URL Azure Portal ==> Storage Account page ==> Endpoints.

azure.storage.accountName=${yourAccontName}
azure.storage.accountKey=${yourAccontKey}
azure.storage.blob-endpoint=${yourAccountBlobEndpoint}
azure.storage.connection-string=${yourAccontConnectionString}

Code

For the service we will create, we define a default method that returns a BlobClient in the interface that must be implemented by classes that want to access the Storage Account. In order to obtain the client, we need the connection string, the container name, and the name of the resource to be accessed. Let's explain for readers who are not storage service users. Our blobs are stored in containers, a container can think like a directory on the filesystem holding a set of files.

default BlobClient getBlobClient(final String connectionString, final String containerName, final String blobName){

return new BlobClientBuilder()
.connectionString(connectionString)
.containerName(containerName)
.blobName(blobName)
.buildClient();
}

We will call this method in the implementer class for operations such as access and upload to blobs.

public String generateAccessUrlWithSAS(final String containerName, final String blobName,
final int amount, final ChronoUnit chronoUnit) {
var blobContainerSasPermission =
new BlobContainerSasPermission().setReadPermission(true);
var builder =
new BlobServiceSasSignatureValues(OffsetDateTime.now()
.plus(amount, chronoUnit),
blobContainerSasPermission).setProtocol(SasProtocol.HTTPS_ONLY);

var client = getBlobClient(connectionString, containerName, blobName);

return client.exists()?String.format("https://%s.blob.core.windows.net/%s/%s?%s", client.getAccountName(),
client.getContainerName(), blobName, client.generateSas(builder)):"Resource not found";
}

In the generateAccessUrlWithSAS method, we will return access URLs of our resources with the shared access signature(SAS) token to our clients. SAS is a URI that grants restricted access rights to Azure Storage resources. We will distribute that URI to our clients to grant them access to our resources for a specified period of time, with a specified set of permissions. For that, we first configure the BlobContainerSasPermission object. The new BlobContainerSasPermission() initializes a BlobContainerSasPermission object with all fields set to false. We give our clients read permission by setReadPermission(true) on the object.

Then we configure the BlobServiceSasSignatureValues object with its constructor that accepts two parameters of type OffsetDateTime and BlobContainerSasPermission. The first parameter defines the expiry time for access and the second permissions.

Notice that the generateAccessUrlWithSAS method has a ChronoUnit type parameter. By passing the ChronoUnit type as the second argument to the plus method of OffsetDateTime, we allowed the user to define declaratively the time specified by the amount parameter in seconds, hours, day, or another type of their choice. We pass the BlobContainerSasPermission object that we just configured as the second argument to theBlobServiceSasSignatureValues object.

In the final step, we obtain the blob client and return the access URL to be valid for the time defined in the parameters passed to the method if the resource exists, if not, we notify the client that the resource is not found.

That is all.

Along with the above method, I have created a repository including the scenario of uploading the specified resource into the storage account, you can examine it.

Conclusion

Azure Blob Storage is Microsoft’s object storage solution that allows you to store a massive amount of unstructured data. It is a good solution for needs such as streaming video and audio, serving images or documents directly to a browser, etc, as they are accessible using REST APIs. Under the com.azure.storage.blob.sas package, there are suitable objects to generate SAS tokens with more concise and readable coding without boilerplate and to meet the grant limited access need.

--

--