In this article we would be covering – JavaScript single-page application, or SPA for short, calling a web API that is secured by Azure AD.

 

 

 

Microsoft Azure Active Directory (AD) is PaaS service available to every Azure subscription, this service is used to store information about users and organizational structure. We’ll use this service as our Authority service which will be responsible to secure our Resource (Web API) and issue access tokens and refresh tokens using OAuth 2 Code flow grant.

The resource (Web API) should be consumed by a Client, so the client will be requesting the data from the resource (Web API), but in order for this request to be accepted by the resource, the client must send a valid access token obtained from the Authority service (Azure AD) with each request.

 

Authentication Protocol Flow
Let’s say there is a sign-in button. By clicking on the sign-in button, the user is then redirected to the Azure AD authorization endpoint.

JavaScript application should be registered in Azure AD as an independent application on itself as a native client application. So it provides the client Id and a reply URL to the request, and the reply URL here is the URL of the browser, but there are things in that request that basically say that it is requesting authentication for this other web API.

So both parties, both the SPA and the web API, should be registered in Azure AD. The browser application, the single-page application, is registered as a native app. And the web API is registered as a web application.

Assuming that they sign in properly, they are redirected back to the reply URL with an Id token in the URL fragments, like as a query string. So, again, that’s why they force HTTPS because if this wasn’t HTTPS, anybody could steal that query string, and that would be really bad. So with that token, then you’re able to call the web API by sticking that token in the header of your HTTPS requests.

The interesting point here is that when the browser makes a request for authentication, Azure AD has no idea who is making that request. The request can come from anywhere. In other words, a sign-in button can live anywhere. However, Azure AD will only send back the Id token to a preregistered reply URL. And you have the flexibility of specifying more than one reply URL, even wildcards, when you register the browser SPA application.

15. SPA Auth workflow

 

OAuth2 Implicit Grant Protocol
OAuth2 Implicit Grant Protocol, and it revolves around this URL. This is a redirection-based flow, the access token is sent back as a query string parameter. In other words, it relies on browser HTTP 302 redirects. It does not authenticate the requester, so the requester sign-in button can live anywhere. But it will only redirect back to the registered reply URL. So that is why, that is how Azure AD ensures that this URL, this access token is not stolen because it is only sent to a preregistered reply URL, which can be a wildcard. It’s up to you. You control what that reply URL can be. And this is why it needs to be HTTPS.

 

Active Directory Authentication Library (ADAL)
To facilitate all of this and make things easy for us, we will use a library called ADAL.JS.  This library will first create an authentication context based on a configuration object in the constructor. Next it will check if the user is authenticated. If the user is not yet authenticated, it will redirect the user to the Azure AD login page. When the user is authenticated (within the right Azure AD tenant), it would a function to acquire an access token for an endpoint defined in the configuration object. Within this function you use this access token to authenticate to the endpoint.

So what happens when the token expires? What ADAL JS does is that it will create an invisible iFrame or a hidden iFrame on the page. And it will, on authentication, it relies on a cookie, so a cookie is established when a successful authentication is done. So when the access token is about to expire, ADAL JS using that hidden iFrame will automatically get a new access token for you. Again, the good news is that because you used ADAL JS, you don’t have to worry about this. You just write your code, and you just use ADAL JS. You focus on your application logic.

What if I had multiple web APIs? So because I’ve signed in once, I don’t need to keep signing in to gain access to other web APIs. ADAL JS will automatically facilitate that for me using that hidden iFrame. There are some requirements on the web APIs of course. So the requirements are the need to support CORS, cross object resource sharing. They need to be registered in your tenancy. Any web API you’re calling needs to be registered. And the consent and permissions should already be in place. 

 

Single Tenant vs. Multi Tenant
The dictionary meaning of a tenant is a person who hires a property on rent. Similarly you may own an office space in a building. This building may be shared by multiple offices. So your office can be considered as a tenant of the building. This building provides all the services to carry out your business well, including security. It also ensures you are isolated from other organizations hosted in the same building.

In Azure, Active Directory service is exactly similar to this concept. It contains many such tenants. So if we want to give it a fancy name, we can say Azure active directory is Multi-Tenant service.

Single tenant applications are ones that you write for your company and that’s all you care about. And multi-tenant are the ones that you write, but the intention is that you are writing them to be used in lots of clients, companies that you don’t control.

Now the interesting thing is that native applications are always multi-tenant. So there is no concept of a single tenant native application. So in the case of single tenant, you go with a native application that is registered multi-tenant anyway. And the web API must also be registered in the same Azure AD as the single tenant application.

 

Demo
There’ll be two web applications. The first one will be an ASP.NET 4.6 MVC-based web API, so a simple REST-based service. Then there’ll be a second web application, and the only reason this is a web application or a Visual Studio project is because I’ll use the web server that comes with it. But, really, this’ll be just an HTML and JavaScript-based application, so very straightforward. And this single-page application written using HTML and JavaScript, especially AngularJS, is going to be able to make a cross-domain call to this web API.

 

Step#1: Create a WebAPI Project
Select the template as MVC, authentication as “No Authentication” and uncheck the checkmark of “Host in the cloud” for now. Click Ok to proceed ahead and create the application.

16. New application

 

Step#2: Configuring Https
We need to configure the project to run on https.

15. Enable SSL

 

Step#3: Project URL

16. Project Url

 

Step#4: Add a model

 

Step#5: Important nuget packages
Open “Package manager console” and run the following commands to add required references to the application.

 

Step#6: Configure Startup class
Adding Support for Cors and Azure AD Auth Support.

 

Step#7: Update the web.config with the required Azure AD details.

9. Service - app config

 

 

Step#8: Create the SPA project

17. new spa project

 

Step#9: Add the required files

12. Client structure

 

Step#10: Update the Index.html

 

Step#11: Update the App.js

 

By doing this, ADAL is injecting an HTTP interceptor. So what it is doing is that it is making sure that if a request that is going to the server receives a 401, then it will automatically redirect me to Azure AD authentication with these parameters so that WebAPI would serve.

 

http://localhost:44300 is nothing but WebAPI Url and https://UrAD.onmicrosoft.com/LocationSvc is the middle man who can authenticate the SPA application to allow access the WebAPI.

 

 

Step#12: Register(as Web app/API) WebAPI service with your Azure Active Directory tenant

1. Register Service

 

Step#13: Register(as Native application) SPA application with your Azure Active Directory tenant

2. Register client

 

Step#14: Update the Audience URl of the WebAPI service

3. Update the Audience URl

 

Step#15: Enable the OAuth2 implicit grant for your WebAPI service

4. Service - oauth2AllowImplicitFlow

 

Step#16: Enable the OAuth2 implicit grant for your SPA application

5. Client - oauth2AllowImplicitFlow

 

Step#17: Configure permissions for your SPA application

6. Client app need permission to talk to Service

20. Service permission

 

Step#18: Set both projects as startup projects.

22. Start up projects

 

Step#19: Run the applications

21. Output

 

Step#20: You can see the Access Token 

18. Access Token

19. JWT