Recently, Microsoft Azure has announced support for using OAuth 2.0 protocol to authenticate Service Management REST APIs. This is something promising since OAuth 2.0 is pretty much the de facto standard for authentication on the web nowadays and it’s relatively easy to understand and reproduce manually compared to OAuth 1. Although the feature is still in preview mode, it works just fine.
This will be a short, proof of concept post explaining how to authenticate the APIs using OAuth 2.0. Below I explained a simple authentication flow:
- Creating an ActiveDirectory application
- Redirecting user to authentication UI
- Obtaining authorization code
- Obtaining OAuth 2 access token
- Making API requests with OAuth 2.0
Let’s dig into it!
1. Creating an ActiveDirectory application
Go to Microsoft Azure Management Portal and create an ActiveDirectory identity directory like this.
After that is created, go to “Applications” tab of the directory and create a new “Native application”. Set a callback URL for your application. (In this example I used http://localhost.)
After your application is created, see its properties. What matters to us here is client id. Save it somewhere.
Then we need to scroll down a bit and give it access to “Windows Azure Service Management API”. (make it Delegated Permissions: 1 and hit “Save”):
After we’re done with that, we just need to get our OAuth 2.0 endpoints. Go back to the applications list, choose our application and click “View Endpoints”:
The ones we are interested in are “OAUTH 2.0 TOKEN ENDPOINT” and “OAUTH 2.0 AUTHORIZATION ENDPOINT”. Save those somewhere as well, because we will use those two to authenticate users and get an access token to make API requests on behalf of them.
(Glad the part with screenshots are finally over. I hate giving instructional screenshots in the technical posts.)
2. Redirecting user to authentication UI
After creating an application and obtaining the “OAuth 2.0 Authorization Endpoint”
URL, you need to redirect the user to this URL. To the ones who are familiar
with OAuth, this is our good old /authorize
endpoint. However we need to make a few
changes to the URL given above. So we will add client_id
and response_type
parameters to that URL, here is how it looks like:
https://login.windows.net/<<YOUR-AD-TENANT-ID>>/oauth2/authorize?client_id=<<GUID>>&response_type=code
Of course, you need to change the required parts using the information we got from portal in the previous step.
If you are building an application, just redirect your user to here to authenticate that account.
3. Obtaining authorization code
If all goes well at the user side and user allows access to your application, you will be redirected to the URL you configured in Step 1, with some extra data on the URL:
http://localhost/?code=<<SOME LONG STRING HERE>>&session_state=<<GUID>>
You will grab that code
value and make the request to grab the access token.
If you made it so far, you are really close.
4. Obtaining OAuth 2 access token
Using the code
value you can do in the server-side application or
the mobile application you are building, we will make Microsoft Azure AD
servers to get an access token to the API.
This could be a bit complicated than usual if you are familiar to the OAuth 2 flow. We will see quite some extraneous parameters required for this step.
The token endpoint is given to you at the end of Step 1. We will be making a POST request there (I don’t know why, ideally it should be a GET request.) We need to write a POST request, whose raw HTTP request looks like this:
POST /<<AD-TENANT-ID>>/oauth2/token HTTP/1.1
Host: login.windows.net
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=<<CODE>>&redirect_uri=<<REDIRECT_URI>>&client_id=<<CLIENT_ID>>&resource=https://management.core.windows.net/
So the corresponding cURL call looks like this for me (replace the URL for your application using the information from Step 1):
curl -X POST https://login.windows.net/<<YOUR--AD-TENANT-ID>>/oauth2/token \
-F redirect_uri=http://localhost \
-F grant_type=authorization_code \
-F resource=https://management.core.windows.net/ \
-F client_id=87a544fd-... \
-F code=AwABAAAAvPM1...8sSAA
Based on programming language and library you use, you can craft a similar request. If you are using an OAuth 2 library, this could make things easier if it’s supporting specifying extra unusual parameters I told above.
The response to this request will be JSON and look like this:
{
access_token: "eyJ0eXAiOiJK......tDTa9kw_OUahg"
token_type: "Bearer"
expires_in: "3599"
expires_on: "1396306283"
resource: "https://management.core.windows.net/"
refresh_token: "AwABAAAAlrEqdF...SVhc_dkOL1VJWJsgAA"
scope: "user_impersonation"
id_token: "eyJ0eXAiOiJKV1QiL.....dfI214SJaW4uY29tI."
}
Our guy is the access_token
token, as you can imagine. This is the only
thing you need to make requests to the API on behalf of the Microsoft Azure
user.
However this guy will expire in 3600 seconds = 1 hour. When that expires, we
have another token called refresh_token
above, which you will use against
the same endpoint to get another access_token
when you need. The token
refresh request will look like exactly the one above, except you need to use:
grant_type=refresh_token&refresh_token=<<REFRESH_TOKEN>>
This will get you a new access_token. However, the refresh tokens could also expire anytime, even though it is not documented. So your applications should handle initiating the authorization flow in case refresh token starts not working anymore.
5. Making API requests with OAuth 2.0
After you get the access_token
it’s quite easy to make the request to the
REST API. For the sake of simplicity in this example, let’s pick
the endpoint of “List Subscriptions” operation. Basically it would look like a
GET /subscriptions HTTP/1.1
Host: management.core.windows.net
x-ms-version: 2013-08-01
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciO.....o-ZeMSUbOlC4YEw
The only thing that is different than the a certificate-authenticated REST API
call is Authorization
header. You need to make this header like:
Authorization: Bearer <<ACCESS_TOKEN>>
The example cURL call looks like this:
curl -v https://management.core.windows.net/subscriptions \
-H "x-ms-version: 2013-08-01" \
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciO.....o-ZeMSUbOlC4YEw"
Given that your access_token
works fine, this will give you the list of
subscriptions in the authenticated account. You can perform other REST API
calls if the AD application is allowed in those subscriptions.
More conveniently, if you are using .NET, you can use the TokenCloudCredentials class within Microsoft Azure Management Libraries for .NET to authenticate with access token to the REST API.
Further reading
Azure PMs Brady Gaster and Vittorio Bertocci both have blog posts on writing a Windows Phone 8 app that uses the Windows Azure Libraries. So if you are going to use .NET or write a mobile application you can certainly learn something out of those.
I just wanted to demonstrate the details of Azure OAuth 2.0 without writing code, just using cURL (or bare HTTP requests), which makes it platform independent. Hope you enjoyed.
Leave your thoughts