Register
Wednesday, May 30, 2012
 
Support this site Minimize
 
 
 
  
 
 Blog
  
Cloud Computing Thoughts Minimize
 
 
 
  
 
History Minimize
   
 
  
 
Cloud Computing Thoughts Minimize
   
 
  
 
Cloud Computing Thoughts Minimize
 
Oct18

Written by:Josef Finsel
10/18/2010 9:30 AM 

Microsoft’s Windows Azure has had a pretty stable authentication scheme since September 2009.  I spent time this weekend updating the AzureCommands library to implement the latest changes to Azure. The biggest headache I encountered was implementing the new Authentication scheme. It turns out there were a couple of things MS did that I didn’t expect and a bug in my own code that  caused some of my grief. Here I’ll document some of what I had to do to implement the new scheme and finish with a Best Practices Guidelines.

Defining the Changes

Microsoft made a number of changes, mostly in the canonicalized resource and canonicalized headers. These changes add more items to what makes up the string to generate the security hash, with more items supposedly being more secure. The new string includes the following values, separated by a new line (\n):

  • VERB
  • Content-Encoding
  • Content-Language
  • Content-Length
  • Content-MD5
  • Content-Type
  • Date
  • If-Modified-Since
  • If-Match
  • If-None-Match
  • If-Unmodified-Since
  • Range
  • Canonicalized Headers (different from earlier versions)
  • Canonicalized Resource (different from earlier versions)

The bold items are new but, as the documentation points out, “where there is no header value, the new line character only is specified.” This means a majority of the hash when creating non-web based interfaces tends to be just new line characters. I started out by modifying my CreateSharedKeyAuth stored procedure to include the new header values. Then it was time to tackle the Canonicalized Resource Changes.

The most obvious change is that the resource is not new line delimited, but there are a couple of other things. First, Query String parameters need to be sorted and can only appear once and their values must be sorted alphabetically.. Thus a legitimate URL that contains include=snapshots&include=metadata&include=uncommittedblobs would need to be include:metadata, snapshots, uncommittedblobs.  So I created a new function to handle that and then created a CanonicalizeUrl2 function to implement all of the new rules.

And promptly got frustrated. Some things like list containers worked fine. Doing anything to container wasn’t working.  This was because I had learned, through trial and error, that I needed to use just a new line character to get past the 401 Forbidden. Except that’s not exactly the case. And this was where I learned the first important lesson of the weekend, perhaps the most important: Fiddler is your friend.

When the server returns a 401 Forbidden error, it also returns a header showing the unhashed string it used to create the authentication. This means you can place the server’s string and your string side by side and figure out what’s wrong. Which lead me to realize that Content-Length should be an empty string when it’s 0 or a GET. Which is really HTTP 101 but it’s been awhile since I’ve done HTTP programming. Once I got Fiddler installed and running and worked through my AuthKey function so I would match, I ran into my second problem, which turned out to be minor modifications in the signature of some of the functions. So I spent some time working with the API docs to make the minor changes like new headers or new query string parameters.  And then I ran into the biggest time sink and it turned out to be my own problem.

Metadata Naming Changes

The first problem I ran into was because I had code to automatically add metadata to show that data was added using my utility, some variation on “x-ms-meta-created-by: Finsel Azure Commands”. Unfortunately, “created-by” is no longer a valid name for metadata. Basically, if you can’t use it as a C parameter, you can’t use it as a metadata name. Once I finally tracked my 400 Bad Request errors to the metadata and changed it, things got easier. But it also exposed a problem.

If you created a blob using the pre-2009-09-19 authentication scheme, it could have metadata that will cause updating metdata using the new scheme to fail! Fortunately, I could blow away and reload my test data without consequences. However, it did get me thinking that I will probably write a utility this week that will walk through containers, blobs and queues and update the metadata names, probably to change anything after a – to be a capital letter (created-by becomes createdBy).

Utility Error

Once I fixed the MetaData naming problem, I ran into another issue of my own making. My AzureBlobLoader was appending an extra / into the blobs it loaded. This turned out to be an insidiously difficult error to track down because it threw 401 Forbidden errors. Once again, Fiddler came to the rescue, showing me the incorrectly formatted URLs and enabling me to figure out what the problem was and to fix it by correcting the utility, deleting the container and re-uploading it. I’ll actually talk more about this later this week when I discuss blobs and changes implemented in the 2009-09-19 version.

Table Storage

Table Storage turned out to only have one modification to the Lite authorization key, and that is the addition of two new headers, making it the easiest of all to implement.

Also, when they released the 2009-09-19 update, they started to return two new headers. x-ms-version is the version used to serve up the response. If you make a request using 2009-07-17 version you’ll see that value returned in the headers. Also, all of the services now return information about the server, “Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0” for example. 

Best Practices

So, after working with and debugging the new authentication scheme, I think the following best practices are in order:

  1. Always specify the version of authentication scheme you are using
  2. Always use the same authentication scheme.
    Technically, you can use the 2009-07-17 version for tables and the 2009-09-19 for blobs but once you’ve worked out the authentication scheme you can use it for everything and having the same authorization scheme simplifies debugging.
  3. Always use the full authentication when possible.
    While you can use a “lite” authentication for Blobs and Queues, it makes more sense to use the standard authentication. Again, it minimizes the amount of debugging and simplifies your programming.
  4. Have Fiddler installed so you can see what differences you and the server are having.
  5. Always implement the latest authentication scheme when possible, with full testing to see what impact those changes may have.

Coming up

Now that I have the latest and greatest changes implemented in AzureCommands, I’ll be laying out the ground work for some outside the box thinking that will help you implement Cloud Computing in some new ways.

Tags:

Your name:
Your email:
(Optional) Email used only to show Gravatar.
Your website:
Title:
Comment:
Security Code
Enter the code shown above in the box below
Add Comment  Cancel 
 
 
  
 
Privacy Statement | Terms Of Use Copyright 2009-2010 by Azure-Architect.com