In mid February Microsoft announced support of the OAuth2 implicit flow by way of a new library called ADAL JS. This is very cool as it allows us to build client-side solutions that can take advantage of Azure AD as a authentication gateway.
You can read more about the OAuth2 implicit flow in my blog post here: Looking at the Different OAuth2 Flows Supported in AzureAD for Office 365 APIs.
What about for the SharePoint or Office 365 developer? Well until today this didn't do anything to help you because these APIs didn't support CORS which is a browser technology that allows you to cross site scripting for services that support it. The service has to support it so if the service doesn’t, it doesn’t matter if the browser supports it. But today, the OfficeDev team announced the both the SharePoint REST API in Office 365 and the Office 365 files API now both support it! So combined with ADAL JS & CORS support you can now create entire single page apps or 100% client side solutions if you want to talk to SharePoint Online or OneDrive for Business.
This week Dan Wahlin and I are presenting at the Angular conference, ng-conf. Our session is about TypeScript, but the sample we created using TypeScript is an Angular application that authenticates with ADAL & talks to the SharePoint Online REST API & the Office 365 Files API… you can grab the sample here if you’re interested.
How does ADAL JS Work?
So how does ADAL JS work? When you need to authenticate, it redirects the user over to the common (aka: multitenant) Azure AD Authorization Endpoint but it only asks for an id_token in the response (you can read more about it in this post). It uses this token to first determine the user’s tenant to build a request to the Azure AD Access Endpoint to get the access token. You can check the source out of the ADAL JS library here. To be clear though, the ADAL JS core library isn't really intended to be used on it's own, rather it's designed to be used in something like the Angular one.
They have also created an ADAL JS Angular library for those using that for their platform. This gives you four very cool additions:
- Angular Service - This is a true Angular service that you can inject into your Angular application.
- Login Events - The login & logout events are broadcast just like other events that you can handle in your application.
- Authentication Required Route Property - Not every route needs to be secured, right? So what they did was create a property that you can add to your routes in the same place where you register your routes template and controller. When the service sees the app try to navigate to that route, if the user hasn’t already authenticated, it forces that first before taking them to the route.
- HTTP Interceptor - The service registers an HTTP interceptor that will listen for HTTP requests to registered resources and if it sees one, it will add the
Authorizationheader with the bearer token in there request… you don’t have to think about it at all!
If you are using this to secure your own custom services you should always check the validity of the JWT bearer token that’s submitted by ADAL JS… don’t just assume if they send one it’s valid. Mat Velloso from the Azure AD team has posted a sample demonstrating how to do this using Node.js.
In order for an Azure AD app to support the OAuth2 Implicit Flow, you need to manually set it as by default apps don’t support it. Do this by downloading the app’s manifest from the Azure Management Portal & changing the property
true. Then upload the updated manifest to the same app.
Want to get some real detail? Check out Vittorio's blog for some great documentation:
Let’s See the Code!
Enough already… show me the code! You can grab this sample form my sp-o365-rest repo, specifically look at the sample adal-cors-client. I’m only focusing on the Angular implementation here in this post, but know that Angular is not required… it’s just how I’m doing it.
First you need to inject the ADAL Angular module into your app:
Then you need to initialize the ADAL provider. This involves telling the provider a few things such as:
- ID of the Azure AD tenant the app is tied to
- ID of the app in Azure AD (aka: client ID)
- collection of endpoints (aka: resources) that you are going to call… these are the endpoints that the HTTP interceptor will watch for calls to and when it finds them, add the required bearer token to the HTTP request
Once configured, when creating your routes, tell the ADAL provider which routes should require that you’re logged in using the boolean property
That’s it! When a user tries to navigate to a protected route, ADAL kicks in. It takes them to the Azure AD Authorization Endpoint to login, grant the app permission to their data (if this is the first time they are using the app) and obtain an OpenID Connect id_token (you can read more about this in my blog post Azure AD, OAuth2 & OpenID Connect). Then when necessary, it obtains an access token whenever it needs one for the requested resource.
What about Office 365 API CORS?
Again, today there is only support for SharePoint Online’s REST API & the Office 365 Files API, but support for the other endpoints are coming soon. Now the best part of this is there is nothing you have to do to take advantage of this… we’ve just been waiting for the service endpoints to support it. Want proof?
Well this simple call to the SharePoint REST API has nothing special in it… it’s a standard call to the REST API:
Now look at what happened on the network. As you can see from the picture below, notice how there was first an HTTP OPTIONS request. The endpoint responded with all the verbs is supports as well as the URLs that are permitted (in this case, all URLs are allowed as indicated by the Access-Control-Allow-Origin response header value:
Then the browser issues another request to the same endpoint as the first response told the browser “yes, I support CORS for specific HTTP requests & the URL you are coming from is allowed… thanks for checking so I’ll now whitelist your domain for a while” and the browser says “ah I see that the service supports CORS for my domain and for the HTTP request I want to make so I can issue it now.” Then it issues the HTTP GET we originally requested with nothing fancy in the request:
This is very cool and thanks to the OAuth2 implicit flow in Azure AD as well as the new ADAL JS libraries, we can make killer SPAs that have zero server side deployment requirements!
Check out all the official Azure AD samples at on GitHub: https://github.com/azureadsamples. Also check out these specific samples:
Mat Velloso form the Azure AD team has posted a bunch of great samples that you should check out as well:
- Demonstrates Angular ADAL JS & CORS
- Demonstrates Angular ADAL JS & CORS with Node.js
- Demonstrates how to use ADAL JS with Ember.js