For enterprises, power users and people who simply don’t like the Azure administration portal but do use Windows Azure as an deployment option for their applications or services it may be desirable to integrate deployment and administration tasks into automatic processes and/or customized tools. To support that Microsoft provides a REST based Service Management API. This API is quite comprehensive and allows you to view and alter your deployments, services and storage accounts. In order to secure access to those resources via the API mutual authentication of certificate over a SSL connection is required. In addition also the Subscription-ID of your account is needed as part of the rest URLs to correctly address your resources. While this is by no means a security feature it is recommended to keep this ID a secret, though. But back to the Certificates now. In order to use the service API you need to have a certificate that you associate with your service API. You can do that by using the developer portal and go to the “Account” page and then use the link “Manage My API Certificates”. Then you are able on import A DER encoded binary representation of your certificate (use certmgr.msc on Windows to do so).
In order to get a certificate for use with the Windows Azure Service Management API there are several possibilities:
It is to note that:
Refer to the API documentation for further information.
No you might ask why do I write all this when this is mostly already documented. Because I got my certificate via the automated process of CAcert.org. And in my first try I run into an error that I was not able to get my Service Management API requests authenticated. The service always returned:
Error 403 (Forbidden): The HTTP request was forbidden with client authentication scheme 'Anonymous'
I didn’t really understand why this was happening as I was creating the certificate in my code using one of the above mentioned DER encoded binary .cer files which I exported from the management console. Here is the code which is really not that complicated.
After a while of investigating I realized that as I created the .cer file from a certificate string shown outlined in the picture below.
However I did not realize that I’m then missing the private key generation process that included by clicking on the install button and uses ActiveX in Internet Explorer.
“Your private key is generated by your browser, *IN* your browser when you request a new cert from CAcert. That way CAcert never has your private key in its possession. The implication for you is that you must be on the same machine using the same browser that you used to request the cert initially, when needing to access your private key. So don't forget if it was your "work" machine vs. your "home" machine.”
Unfortunately I couldn’t get that to work with IE8 and Windows 7 what brought me to use the certificate string in the first place. But if you walk down this road and copy that string into a text file, change the file extension to .cer and then install the certificate you will not have a private key associated with this certificate and that’s why the request is failing. In order to have the requests working you need to meet two prerequisites for your certificate:
For me this meant:
After all those steps I was able to issue successful requests with my own code as well as available tools to interact with the Windows Azure Service Management API such as csmanage.exe or the PowerShell Windows Azure Service Management CmdLets. However just to note it again this only works because the certificate is actually also installed in the certificate store where the .Net Cryptographic API does a lookup of the certificate and its corresponding private key. You can verify this if you import the certificate in step 4 above to prompt you if an application tries to use the private key of this certificate.