Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Consuming Windows Azure Service Management API in a Windows 8 Application

DZone's Guide to

Consuming Windows Azure Service Management API in a Windows 8 Application

· Cloud Zone
Free Resource

Are you joining the containers revolution? Start leveraging container management using Platform9's ultimate guide to Kubernetes deployment.

In this post, we're going to use a Windows Azure Service Management REST API with a Windows 8 application. I built a small app that lists the storage accounts in a subscription as a proof of concept. Since I’m more comfortable with XAML/C# than HTML5/JavaScript, I built this application using the former, though in the course of exploring for this project, I did build a small prototype using HTML5/JS. I’ve included relevant code snippets of that as well.

X509 Certificates

As you know, Windows Azure Service Management REST API makes use of X509 certificate based authentication. When I started looking into it, first thing I found was that there’s no direct support for X509 certificates in .Net API for Windows 8 applications. I almost gave up on this when Mike Wood (http://mvwood.com/ & http://twitter.com/mikewo), a Windows Azure MVP pointed me to this documentation on MSDN for building Windows 8 applications: http://msdn.microsoft.com/en-us/library/windows/apps/hh465029.aspx. Well, what followed next is non-stop coding of various trials and errors.

In short, there’s no direct support for X509 certificates in the core API (like what you have available in standard .Net API) but it does allow you to install an existing PFX certificate in your application certificate store. This is accomplished via ImportPfxDataAsync (C#) / importPfxDataAsync (JavaScript) method in Windows.Security.Cryptography.Certificates.CertificateEnrollmentManager class. Here’s the code snippet to do the same:

C#:

await Windows.Security.Cryptography.Certificates.CertificateEnrollmentManager.ImportPfxDataAsync(
    encodedString,
    TextBoxPfxFilePassword.Password,
    ExportOption.NotExportable,
    KeyProtectionLevel.NoConsent,
    InstallOptions.None,
    "Windows Azure Tools");

JavaScript:

Windows.Security.Cryptography.Certificates.CertificateEnrollmentManager.importPfxDataAsync(certificateData2, "", Windows.Security.Cryptography.Certificates.ExportOption.exportable,
    Windows.Security.Cryptography.Certificates.KeyProtectionLevel.noConsent, Windows.Security.Cryptography.Certificates.InstallOptions.none, "My Test Certificate 1")

Here encodedString is Base64 encoded PFX file data, something like this (click to enlarge):

image

and the password is the password for your PFX certificate file.

When you call this method, the application should install a certificate in your application certificate store. You can check it by going into the “AC/Microsoft/SystemCertificates/My/Certificates” folder under your application package directory. The package directory is created under your user account’s “AppData/Local/Packages” folder as shown in the screenshot below (click to enlarge):

image

Please note that name of the file will be the thumbprint of the certificate.

That’s pretty much to it as far as working with PFX files are concerned. However, there are some important issues to understand when these certificates are used to authenticate REST API calls. I spent about 24 – 48 hours trying to make this work. Please see “Special Considerations” section below for those.

Consuming a REST API

Consuming a REST API was rather simple! If you’re using C# you would make use of HttpClient in System.Net.Http namespace, and if you’re using JavaScript you would make use of WinJS.xhr function which is essentially a wrapper around XMLHttpRequest. Here’s the code snippet to do the same:

C#:

private const string x_ms_version_name = "x-ms-version";
private const string x_ms_version_value = "2012-03-01";
Uri requestUri = "https://management.core.windows.net/[your subscription id]/services/storageservices";
 
public static async Task<string> ProcessGetRequest(Uri requestUri)
{
    HttpClientHandler aHandler = new HttpClientHandler();
    aHandler.ClientCertificateOptions = ClientCertificateOption.Automatic;
    HttpClient aClient = new HttpClient(aHandler);
    aClient.DefaultRequestHeaders.Add(x_ms_version_name, x_ms_version_value);
    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUri);
    var result = await aClient.GetAsync(requestUri, HttpCompletionOption.ResponseContentRead);
    var responseBody = await result.Content.ReadAsStringAsync();
    return responseBody;
}

JavaScript:

var uri = "https://management.core.windows.net/[your subscription id]/services/storageservices";
WinJS.xhr({ url: uri, headers: { "x-ms-version": "2012-03-01" } })
    .done(
       function (/*@override*/ request) {
           var responseData = request.responseText;
       },
       function (error) {
           var abc = error.message;
       });

That’s all there is to it. If your request is successful, you will get response data back as XML which you can parse and use it in your application.

Special Considerations

It sounds pretty straightforward, but unfortunately it is not so. I spent between 24 and 48 hours trying to figure this whole thing out. I was able to install the certificate correctly but then when I invoked the REST API using C# code, I was constantly getting 403 error back from the service. I ended up on this post on MSDN forums: http://social.msdn.microsoft.com/Forums/sv/winappswithcsharp/thread/0d005703-0ec3-4466-b389-663608fff053 and it helped me immensely.

Based on my experience, here are some of the things you would need to take into consideration:

Ensure that “Client Authentication” is enabled as one of the certificate purpose

image

Your certificate must have this property enabled (as shown in the screenshot above) if you wish to use this certificate in your Windows 8 application. Please note that when consuming a REST API in your non-Windows 8 applications, it is not required that this property is set.

Ensure that the certificate has “OID” specified for it

image 

Based on the MSDN forum thread above, this is a bug with Microsoft.

image

HttpClient and WinJS.xhr are not the same

I started with building a XAML/C# application (because of comfort level) and no matter what I tried, I could not make the REST API call work. It was only later I was made aware of the 2 issues above. However I took the certificate which was giving me problems (because of 2 issues above) and built a simple HTML5/JavaScript application and it worked like a charm. You would still need to have “Client Authentication” enabled in your certificate but not the OID one when consuming Service Management API through JavaScript.

It may very well be an intermediate thing (because of OID bug mentioned above) but I thought I should mention it here.

Try avoiding “Publish Profile File” if you’re consuming a REST API in XAML/C# application

Publish Profile File, as you know is an XML file containing information about all your subscriptions (Subscription Id etc.) and Base64 encoded PFX certificate content. It’s a great way to get access to all your subscriptions. The reason I’m saying you should avoid it here is because what I found is that the PFX certificate from which the content is generated currently missing OID in there. So till the time Microsoft fixes this issue, please go individual certificate route if you’re developing using C#/XAML. If you’re building using HTML5/JavaScript, you can write something which will import this file as based on my testing it works. Just remember that the password for the certificate is an empty string. So specify an empty string (“”) for the password parameter in your call to importPfxDataAsync method.

Recommend that you create a new management certificate if you’re consuming a REST API in C#/XAML application

Again this is because of the issues I mentioned above. You will need to check if the certificates you have in place today do not have the 2 issues I mentioned above. You can use “makecert” utility for creating a new certificate. I was recommended the following syntax for creating a new certificate.

makecert -r -pe -n "CN=[Your Certificate Common Name]" -b 09/01/2012 -e 01/01/2099 -eku 1.3.6.1.5.5.7.3.2 -ss My

Run this in “Developer Command Prompt” on a Windows 8 machine to create a new certificate which will get automatically installed in your computer’s certificate store. You can export that certificate using “certmgr” utility.

The App

Finally, the moment of glory. It’s really a simple application -- I've included some screenshots below. You can download the source code here.

Landing page with no subscriptions saved

image

Add subscription page

image

Landing page with saved subscriptions

image

Storage accounts list page

image

A few things about this application:

  • I wrote this application in a few hours' time (after spending about two days trying to figure everything else out), so the code is not perfect.
  • There’s a glitch currently in the application where if you add 2 subscriptions with different certificates, one of the subscription will not work. I haven’t figured it out just yet. For this application I would recommend that you use same certificate for all your subscriptions.
  • The application saves the subscription id and friendly name in JSON format in application’s local settings and is not encrypted.

Acknowledgements

I’m grateful to Jeff Sanders from Microsoft for promptly responding to my questions on MSDN forums and offline as well. I’m equally grateful to Harin Sandhoo from Applied IS, who basically provided me with everything I needed to make this thing run in a XAML/C# app. Also many thanks to Mike Wood for letting me know about working with certificates in Windows 8. Without Mike’s help, I would have given up working on this thing. Lastly, thanks to Patriek van Dorp for asking a question about consuming Windows Azure Service Management API in a Windows 8 App. That pushed me into thinking about building this application.

Using Containers? Read our Kubernetes Comparison eBook to learn the positives and negatives of Kubernetes, Mesos, Docker Swarm and EC2 Container Services.

Topics:

Published at DZone with permission of Gaurav Mantri, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}