Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / API

Azure AD: Securing Your API with Zero Code

5.00/5 (5 votes)
28 Dec 2015CPOL7 min read 14.4K  
Azure AD: Securing your API with zero code

Originally posted on: http://geekswithblogs.net/PaulNichols/archive/2015/12/18/azure-ad-securing-your-api-with-zero-code.aspx.

See how Microsoft now enables you to add authentication to your Azure APIs with zero code. Also, save yourself time by seeing how to call those API securely.

Firstly, I'd like to say that Microsoft has made securing an API extremely simple with, as they describe it, a turn-key solution. Saying that I still managed to make hard work of this myself so I wanted to document the steps to help others save time.

For all the articles I read on the subject, I still had one piece of the puzzle wrong in my client application. I’d like to show you in this article how I diagnosed and avoid such problems…

I’m going to take you through step by step how to deploy an API app, secure it and then write a console application to access the API.

If you’re like me, you probably find security one of the hard parts of development? Writing the features is fun but deploying that code into production in a secure way is less fun.

Download code here.

Deploying and Securing a WebAPI Application

Let's start by allowing Visual Studio 2015 to generate an API with no security, and then upload that to Azure. We'll then have an API that technically the whole world has access to, hence the need for security.

Choose File > New > Project

Ensure you select the Azure Subscription you’d like to publish to:

NewProject

Next select the WebAPI option (notice that I’ve chosen no Authentication on the right hand side of the dialog).

NewWebApp

Then, you’ll be prompted to create a new App service plan.

App Plan

Once you’ve set up the App service plan (details of which I won’t go into here) and you click create, you will be presented with your new WebApi application

You’ll notice if you expand the solution in the Solution Explorer that there is a values controller by default. This is what we will secure and then query via our test client.

image

You’ll notice when you look at the code, there’s no Authorize attribute so when we deploy this API app, it will be sans Authentication/Authorization!

Right, let’s deploy this plain API app to Azure. Right click on the API project in the Solution Explorer and select Publish. When this dialog appears, select “Microsoft Azure App service” as the target of your deployment.

image

In the next dialog, drill down until you find the App service plan you created earlier and then select and publish. Check Visual Studio’s output window and with any luck, your API app will now be deployed to Azure.

Your site should pop up in your web browser. If you then append /api/values to the address, you should see the following, an XML list of values …

api

So far so good. Now for the interesting bit.

Navigate to the new Azure portal https://portal.azure.com and select the Resource Group you published your API to.

In the resources blade, select your API site and click on Settings so that the following blade appears. Choose “Authentication / Authorization”.

settingsblade

Turn on Authentication and select Azure AD as the provider.

auth

Now comes the magic, select Express mode and go with the AD App name selected for you. Click OK and click Save

Two weeks before writing this tip, this dialog didn't work and caused me all sorts of problems! The express mode didn't seem to create an application in any AD as far as I could see and there was no ability to search for an existing app. This is the beauty of Azure, it's always changing.improving :)

ad

What this will now do for you is to create an Application in your Azure AD directory. In our case, this is the app the client will Authenticate with as well as the app the API is secured with. The doesn’t have to be the case. You can have an application for each of your APIs and then one for your client which has permissions to access all the API applications. This will be in a later article.

Now if you swap to https://manage.windowsazure.com and navigate to our AD directory, select applications and you should see your newly created and correctly configured Application. If not, then select “Applications my company owns” from the search filter and click the tick to search.

directory

If you go back to your web browser now and try to GET the values from the API, you should find the API is secured and you never had to write a line of code or config!!

Excellent, but this is where I got a little confused and made hard work of the few lines of code required to create a client Console app and access the API securely.

Creating a Client Application to Call the Secured WebApi Application

What the console app will do is first get a bearer token from the AD application to access the secured resource, then add that token to an authorization header before calling the API for the values.

I won’t tell you how to create a Console App, but when you have then copy and paste the Program.cs and app.config code from here into your app.

First, let's look at the config:

XML
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup>
        
<supportedRuntime version="v4.0" 
sku=".NETFramework,Version=v4.5.2" />
    </startup>
  <appSettings>
    <add key="AADInstance" 
value="https://login.windows.net/{0}" />
    <add key="Tenant" 
value="" />     <!-- Azure AD tenant -->
    <add key="ClientId" 
value="" />     <!-- Client ID of the secured api app  -->
    <add key="ApiResourceId" 
value="" />    <!-- Client ID of the secured api app -->
    <add key="ApiBaseAddress" 
value="<a href="https://paultestauthapi.azurewebsites.net/"">"</a> />    <!-- Actual URL where Web API is hosted -->
    <add key="AppKey" value=""/> <!-- generated secret from the secured api app -->
  </appSettings>
</configuration>

To get these configuration values, navigate to the Configure tab of your AD app.

The Client Id is on the configure tab and if you then select the drop down in the Keys section and click save, you will see an app key/secret generated. This will disappear once you leave this page (but you can generate it again) so copy it now.

key

Finally, you need the name of your AD tenant. This will be your domain/email address or you can use the GUID found in the Endpoints option at the bottom of the AD Application page you’re currently on.

Now let's look at the code.

We’ll first see that we construct some credentials to call the app we are getting the bearer token from. In some cases, this can be an AD app that has access to many APIs, in this case we will just use the same app to authenticate with as the app the API is secured against.

C#
ClientCredential clientCredential =  ClientCredential(clientId, appKey);

We then ask AD for the token:

C#
AuthenticationResult authResult = authContext.AcquireToken(apiResourceId, clientCredential);

And that single line of code was my big problem I had the wrong resource identifier. When I finally had everything working, I was using the Client ID of the resource I was trying to access so there was no ambiguity of which resource I was talking about. Further down the article, I will explain how I fixed my 401 Unauthorized issue that lead me to start using the resources Client Id.

One we have the token, we need to add that to the header before we make the call to the service.

JavaScript
httpClient.DefaultRequestHeaders.Authorization = 
	new AuthenticationHeaderValue(authResult.AccessTokenType, authResult.AccessToken);

The final lines of code call the values controller and when you run the Console App, all being well, you should receive a 200 which shows you’ve successfully called the secured API with the correct authentication.

Well done!

How to Diagnose Authentication Issues

I just wanted to take a moment to explain how I worked out why, for a very long period of time, I was getting a status code of 401.71 Unauthorized.

Turn On Site Logging

Firstly turn on logging.
In the new portal, navigate back to the settings blade of your Web API app. Select “Diagnostics logs” and then configure that blade like this and save. Your site should now log all incoming HTTP calls.

logs

Kudo to the Rescue

If you navigate to https://WhereEverYouPublishedTheAPITo.scm.azurewebsites.net/DebugConsole (notice the scm part of the URL), then you will find yourself in the Kudo Debug console. Then, select the CMD option up in the Debug Console menu, this will take to a site explorer.

kudo

Go to the LogFile folder, then Application. In there, you will find log file that show you the HTTP calls coming in and if they were successful, and if not the code and reason why not. Invaluable!

With this help, I was able to work out how to fix my client app.

Hope this will save someone else a little time. :)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)