Getting Azure AD access token via REST Call

Part of Azure experiment, one of my colleagues started playing with Azure API Management last week. He was interested with what I introduced about the service, including API gateway, API publishing portal to readable policies to manipulate inbound request before back-end hit. He also loved to work with API call via REST because API is a flexible way of touching Azure resources through pure HTTP request, without installing any specific library.

After a few days, he came asking for help because he was unable to authorize request before calling Azure API Management REST API. I pointed him to this reference to make sure he understood that he needed to have authorization to Azure AD before working with any Azure resource and service. I also followed the guidance in the reference but then realized that this article was obsolete and seem to be wrong (in my opinion). Every time when I tried to send a GET  or POST  request with valid structure as well as authorization header, I always got a message telling me the authorization header format was invalid.

From what I tested, including new authentication updates in Azure AD, I personally believe the reference I just mentioned above is obsolete.

To support my colleague, I started looking into the issue and finally found a solution. In this article, I’d like to point out some notes, including references and sample code for you to get started with authenticating Azure AD via OAuth 2.0 with access token before working with any of Azure service’s REST API.

Why do you need to get access token?

First, we need to understand that Azure AD is the core identity & access management system of Microsoft Azure platform. Moreover, it is not the only identity system being used internally in Microsoft. It offers comprehensive identity solution for cloud services. One of the well-known cloud services which is consuming Azure AD is Office 365. If you have ever worked with Office 365 or SharePoint Online, you must know that setting up hybrid identity between your on-premises Active Directory and SharePoint Online require a trust from Azure AD.

When you make a call request to Azure REST API, it asks you to give something it trusts. One of so-called trusts  is access token. Access token is a form or security token that your application can use to access Azure resources (in this case Azure REST API) which are secured by authorization server (aka Azure AD endpoint). This is part of the entirely OAuth architecture which Azure provides. Access token is not the only way to get authorized to Azure AD. For other types of tokens, refer to this article.

Building authentication helper class

It is hard to find an up-to-date article over the Internet to cover getting access token programmatically. You can manually get the access token by browsing number of different URLs to copy an access token. That is a quick way before you can test other services (such as getting Azure Key Vault secret). As a developers, however, that is not something you want because access token is supposed to automatically generated and become an object before you can use it for further API operations.

I spent a few hours to vet through Google to see if anything I could use to get started. Fortunately, I found this article written by David Ebbo which is helpful to look at. In the article, David demonstrated the way to get access token using HttpClient . However, this article was written over 2 years ago. Moreover, the article just worked with Azure Service Management (Azure Classic model) endpoint which has been deprecated today. There are three parts in David’s sample code:

  • AuthenticationHelpers.cs: this class contains method to get access token
  • Program.cs: this class contains your function to perform REST API operation after having access token.
  • LoggingHandler.cs: this class contains function to log calls to web API which he used from this article.

First, you need to declare constant fields which you must not modify. The fields include the following things:

  • Management request URI
  • Authorization endpoint
  • Service Principal payload

Management request URI we need to use is for ARM (Azure Resource Management) endpoint. Previously the ASM model used https://management.core.windows.net  but it seems to work for ARM model. The new URI is https://management.azure.com. I cannot seem to find a good resource to indicate the difference between the two (perhaps based on API version).

For the authorization endpoint, the new one is https://login.microsoftonline.com/{tenantId}/oauth2/token  which is the v.2 endpoint Microsoft give details here.

You also need to pass required parameter when calling to the URI. The parameter include resource  you need to get access token. In this case, it is Azure AD’s tenant ID. client_id  is your application ID you can get after registering it in Azure AD. client_secret  is given by Azure AD.

Now the declaration looks like

For the rest of the code, I resused from David’s code. The code below formats the payload with three important parameters passed to. It then make a POST request using HttpPost  to get the access token.

This is not enough to fully make a request to work. The full HTTP POST request also needs to indicate Content-Type header which is application/x-www-form-urlencoded . That is why we need the following code snippet

Below is the sample POST request to request an access token

David’s code also adds more methods to trace the return to make sure the request is successful with status code “200”.

There are a couple of notes if you use the code in a fresh development environment:

Getting & Setting Azure environment variable

In previous section, you declared three fields tenantId , client_id  and client_secret  you might wonder where to get these things. This section, I’d like to walk you through steps to get these things via PowerShell.

First, you need to login to Azure AD using Login-AzureRmAccount . You are asked to give the credential when using this cmdlet. After, connect to your Azure AD. If you use Microsoft Account (aka MSA), go to read the below to make sure you don’t connect to Azure AD which your account is being managed.

Connect to Azure AD using Microsoft Account with PowerShell

There are two main cmdlets you can use to perform app registration in Azure AD.

  • New-AzureRmADApplication
  • New-AzureRmADServicePrincipal
  • New-AzureADApplicationPasswordCredential

Run the following PowerShell to create a new app and register it into Azure AD. The “term” app doesn’t really mean “app” in App Store or any app in your mobile phone. It represents a client which needs to be authorized in Azure AD.

Now you need to grab client secret by open Azure AD Portal > App registrations. Choose the new app you just created and verify if output in PowerShell matches the info under app blade.

Until now, you have all the fields you need for the authenticationhelper class.

Storing Azure App configuration setting

Basically you can declare and assign value for tenantId , client_id  and client_secret  directly into the field. For example

However, this way is not a recommended best practice for security. Moreover, environment configuration should be controlled separately. Ideally, configuration should be stored in app.config  file. In David’s sample core, he used System.Configuration.ConfigurationManager  to manage external configuration. However, since we work with Azure, I’d like to introduce a new package named Windows.Azure.ConfigurationManager  which is used to load configuration.

Open App.config file and paste configuration information inside <configuration>  element.

At this time, I’ve completed the configuration setup for my team and ready for requesting access token with given value.

Making a sample request call to API Management 

This section is additional to testing Azure REST API after you get access token and complete your HTTP request body (including authorization header). Let’s declare and add more things to Program.cs . Below is my declaration for resource group name, location and my API Management service. Note that this is API Management service, not Azure REST API. My purpose is to use REST to retrieve information of my API Management service named s15digital.

Now I need to load configuration from App.config file. Because I use WindowsAzure.ConfigurationManager assembly so I need to modify David’s sample code. Note that GetSetting()  method is used with bracket () instead of square bracket [].

You then need to load other configuration settings, initizlize a new HttpClient object and append its request body.

Do note that the full authorization header must have the structure ("Authorization", "Bearer " + token)

Now let’s define getAPIinfo  method which includes the full query string and HTTP GET method with GetAsync()

Not that the structure I declared in url  string. If you follow my article until now and run the program, you will always get the 403 (Forbidden) error.

Trace information output can be managed if you use LoggingHandler  function from David’s sample code. And also make sure you pass parameters when initializing HttpClient  object.

Why do we get this error? This error doesn’t mean you have no access to Azure Management API. Instead, it tells you that you have no authorization to the target API Management service, namely s15digital. In this case, you need to give the service principal a role by using the following PowerShell (followed by the previous PowerShell to register an application).

After running the script above, you can check via Access control (IAM) of the target API.

Let’s run the program again and verify the output. The JSON output is my API Management service I created in Azure API Management. By default, it contains default Echo API.

You can get access token and test with RESTClient extension in Firefox browser

Conclusion

Getting access token requires several steps to set up and get required information. The access token is as important as if it is compromised I could do something to retrieve your Azure service information.  This article just showed you how to initialize HttpClient  object to call Azure Management API via REST. I’d like to give my appreciation, thank and the credibility to David’s article and his sample code on GitHub.

Once again, if your application needs to have access to Azure resources before any operation you’d make,it needs to be authorized by Azure AD because identity & access of Azure resources are controlled and managed by Azure AD. Once you get access token, you can include it in authorization header when making a HTTP request again the target Azure API services. In my article, I demonstrated how to retrieve my Azure API Management service with GET method.

Comments

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

© 2018 The Soldier of Fortune.