Click here to Skip to main content
Click here to Skip to main content
Technical Blog

Tagged as

Authorization request signing for Windows Azure Storage REST API from PowerShell

, 18 Apr 2014 CPL
Rate this:
Please Sign up or sign in to vote.
Recently, while working on one of the Windows Azure migration engagement, we were need to have a simple and portable utility scripts that manipulate on various Windows Azure Storage (WAS) services APIs like “Get all blob metadata details from selected containers”.  This is further enable

Recently, while working on one of the Windows Azure migration engagement, we were need to have a simple and portable utility scripts that manipulate on various Windows Azure Storage (WAS) services APIs like “Get all blob metadata details from selected containers”.  This is further enabled to perform various manipulations for the business.

There are various options like LINQPad queries, WAPPSCmdlets or Azure Storage Explorer + Fiddler.  However, in-terms of considering the computation post to the WAS invocation, repetitiveness of the work and considering the various type of users environment, simple PowerShell script is the option.  So, I have decided to write simple PowerShell script using WAS REST API.  This does not require any other snap-in or WAS storage client assemblies. (Re-inventing the wheel?!)

One of the main hurdle is creating Authorization header (signing the request).  It should contains the following:

  • HTTP verb
  • all standard HTTP headers, or empty line instead (canonicalized headers)
  • the URI for the storage service (canonicalized resource)

A sample string for the signing mentioned below:

<div id="LC1">GET\n /*HTTP Verb*/</div>
<div id="LC2">\n /*Content-Encoding*/</div>
<div id="LC3">\n /*Content-Language*/</div>
<div id="LC4">\n /*Content-Length*/</div>
<div id="LC5">\n /*Content-MD5*/</div>
<div id="LC6">\n /*Content-Type*/</div>
<div id="LC7">\n /*Date*/</div>
<div id="LC8">\n /*If-Modified-Since */</div>
<div id="LC9">\n /*If-Match*/</div>
<div id="LC10">\n /*If-None-Match*/</div>
<div id="LC11">\n /*If-Unmodified-Since*/</div>
<div id="LC12">\n /*Range*/</div>
<div id="LC13">x-ms-date:Sun, 11 Oct 2009 21:49:13 GMT\nx-ms-version:2009-09-19\n /*CanonicalizedHeaders*/</div>
<div id="LC14">/udooz/photos/festival\ncomp:metadata\nrestype:container\ntimeout:20 /*CanonicalizedResource*/</div>

Read http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx and particularly the section http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx#Constructing_Element for request signing of “Authorization” header.

I have written a simple and dirty PowerShell function for blob metadata access.


function Generate-AuthString
{
param(
[string]$url
,[string]$accountName
,[string]$accountKey
,[string]$requestUtcTime
)

$uri = New-Object System.Uri -ArgumentList $url

$authString =   "GET$([char]10)$([char]10)$([char]10)$([char]10)$([char]10)$([char]10)$([char]10)$([char]10)$([char]10)$([char]10)$([char]10)$([char]10)"
$authString += "x-ms-date:" + $requestUtcTime + "$([char]10)"
$authString += "x-ms-version:2011-08-18" + "$([char]10)"
$authString += "/" + $accountName + $uri.AbsolutePath + "$([char]10)"
$authString += "comp:list$([char]10)"
$authString += "include:snapshots,uncommittedblobs,metadata$([char]10)"
$authString += "restype:container$([char]10)"
$authString += "timeout:90"

$dataToMac = [System.Text.Encoding]::UTF8.GetBytes($authString)

$accountKeyBytes = [System.Convert]::FromBase64String($accountKey)

$hmac = new-object System.Security.Cryptography.HMACSHA256((,$accountKeyBytes))
[System.Convert]::ToBase64String($hmac.ComputeHash($dataToMac))
}

 

Use [char] 10 for new-line, instead of “`r`n”.

Now, you need to add “Authorization” header while making the request.


[System.Net.HttpWebRequest] $request = [System.Net.WebRequest]::Create($url)

...

$request.Headers.Add("Authorization", "SharedKey " + $accountName + ":" + $authHeader);

The complete script is available at my GitHub repo https://github.com/udooz/powerplay/blob/master/README.md.

The real power when accessing REST API from PowerShell is the “XML processing”.  I can simply access ListBlob() atom fields like


$xml.EnumerationResults.Blobs.Blob

Happy Coding.

License

This article, along with any associated source code and files, is licensed under The Common Public License Version 1.0 (CPL)

Share

About the Author

M Sheik Uduman Ali
Architect Aditi
India India
Working as Architect for Aditi, Chennai, India.
 
My Website: www.udooz.net
 
My Blog: www.udooz.net/blog
Follow on   Twitter

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150129.1 | Last Updated 18 Apr 2014
Article Copyright 2014 by M Sheik Uduman Ali
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid