1 week with Microsoft Azure REST API

I am a senior software engineer at ServMask Inc. I recently created an extension to our All-in-One WP Migration plugin that connects to Microsoft Azure Storage. This facilitates backing up WordPress websites directly into Microsoft Azure Storage.

From the beginning I was skeptical about this platform. We all know about the many problems we often encounter when using products created or maintained by Microsoft, and this has led me to think that it will not even be different here.
This thought followed me constantly in the development of this plugin and at least for a moment I was right.

What made me very impressed was that they had a very large set of services. Undoubtedly, this has led to problems with my orientation in their documentation. To find what I needed, I had to spend some time. However, I managed to find the resources I needed and I was able to continue with the development.

Surprisingly for me, everything was well described. We’ve all come across documentation that is not well structured, and it’s pretty hard to get into them. Here the problem was absent.

It also worked as described. I have often encountered any problems with other similar services. Most often, problems are related to poorly functioning methods or not working at all. However, I have not been able to encounter such problems here. Everything worked smoothly, and here was the moment when I began to change my mind about this service.

In the process I learned more about the service itself and I thought it would be useful to share them.

Microsoft Azure Storage Account

Azure’s storage service provides durable, scalable, and redundant storage. All access to storage services takes place through the storage account. The storage account is the highest level of the namespace for accessing each of the fundamental services. It is also the basis for authentication.

Azure Storage Service elements

  • Blob storage – Blobs are unstructured files like those that you store on your computer. Blob storage can store any type of text or binary data, such as a document, media file, or application installer. Blob storage is also referred to as object storage.
  • File storage – The Azure Files service enables you to set up highly available network file shares that can be accessed by using the standard Server Message Block (SMB) protocol. This means that multiple VMs can share the same files with both read and write access. The files can also be accessed using the REST interface or the storage client libraries. This is the storage that the Microsoft Azure Storage Extension connects to.
  • Table Storage – This storage is a service that stores structured NoSQL data in the cloud. Table storage is a key/attribute store with a schema-less design. Because Table storage is schema-less, it’s easy to adapt your data as the needs of your application evolve. Access to data is fast and cost-effective for all kinds of applications. Table storage is typically significantly lower in cost than traditional SQL for similar volumes of data. You can use Table storage to store flexible datasets, such as user data for web applications, address books, device information, and any other type of metadata that your service requires. You can store any number of entities in a table.
  • Queue storage – The Azure Queue service is used to store and retrieve messages. Queue messages can be up to 64 KB in size, and a queue can contain millions of messages—up to the maximum size of a storage account. Queues generally are used to create a list of messages to be processed asynchronously. The Queue service supports best-effort first in, first out (FIFO) queues.

The REST APIs for storage services expose the storage account as a resource. For example:

https://[storage account name]/blob.core.windows.net/[container]/[blob name]

There are 3 types of storage accounts

  • Standard storage account – This is the most commonly used account and we can use it for all four types of data (blobs, files, tables, and queues). This account is suitable for use with the All-in-one WP migration Azure extension.
  • Premium storage account – provides high-performance storage for page blobs and specifically virtual Azure Storage hard disks (VHDs). This account also uses SSD to store data. This account is suitable for use with the All-in-one WP migration Azure extension.
  • Blob storage account – This account is a specialized storage account used to store block blobs and append blobs.FYI only

One Azure Storage subscription can host up to 100 storage accounts, each of which can hold 500 TB. This can be increased to 250 storage accounts but putting a business case to the Azure Storage team.

Security

Every account has two authentication keys: primary and secondary — either of which can be used for any operation.

The most challenging part of creating the All-in-one WP migration Azure extension was to determine the correct usage of the Authorization Header which is required to be passed to use the REST APIs. This header complicates application builds and had me stumped for a while, so I’ll share what I learned here

There are five basic steps for calculating this header. In this example I will provide the PHP code that I wrote:

  1. Create a Canonical Request for Signature:
    function prepare_canonical_request( $method, $path, $query = array(), $headers = array() ) {
    	$canonical_url = array();
    
    	// Start with the HTTP request method (GET, PUT, POST, etc.)
    	$canonical_url[] = $method;
    
    	// Set the canonical headers
    	$canonical_headers = array();
    	foreach ( $headers as $key => $value ) {
    		$canonical_headers[ strtolower( $key ) ] = trim( $value );
    	}
    
    	// Sort the canonical headers
    	ksort( $canonical_headers );
    
    	// Add the canonical headers
    	foreach ( $canonical_headers as $key => $value ) {
    		if ( stripos( $key, 'x-ms-' ) === 0 ) {
    			$canonical_url[] = sprintf( '%s:%s', $key, $value );
    		} else {
    			if ( strcasecmp( $key, 'Content-Length' ) === 0 && intval( $value ) === 0 ) {
    				$canonical_url[] = null;
    			} else {
    				$canonical_url[] = sprintf( '%s', $value );
    			}
    		}
    	}
    
    	// Add the account name and path
    	$canonical_url[] = '/' . $this->account_name . $path;
    
    	// Set the canonical query parameters
    	$canonical_query = array();
    	foreach ( $query as $key => $value ) {
    		$canonical_query[ strtolower( $key ) ] = trim( $value );
    	}
    
    	// Sort the canonical query parameters
    	ksort( $canonical_query );
    
    	// Add the canonical query string
    	foreach ( $canonical_query as $key => $value ) {
    		$canonical_url[] = sprintf( '%s:%s', $key, $value );
    	}
    
    	return implode( "\n", $canonical_url );
    }
    
  2. Create a String to Sign for Signature (2018-03-28):
    function prepare_string_to_sign( $canonical_url ) {
            return utf8_encode( $canonical_url );
    }
    
  3. Calculate the Azure Signature (2018-03-28):
    function calculate_signature( $string_to_sign ) {
    	// Calculate the signature
    	$signature = hash_hmac( 'sha256', $string_to_sign, base64_decode( $this->account_key ), true );
    
    	// Base64 the signature
    	$str_base64_signature = base64_encode( $signature );
    
    	return $str_base64_signature;
    }
    
  4. Build string for Authorization header:
    function build_authorization_string( $str_signature ) {
    	return 'SharedKey ' . $this->account_name . ':' . $str_signature;
    }
    
  5. And last step – set header “Authorization” with value of returned string from build_authorization_string function.

Leave A Comment?