Posted by on Oct 28, 2015 in #Office365Dev | 0 comments

When building add-ins for Office – you will often find yourself in need of calling secured services (the Office 365 APIs for instance).

Today, many of the modern services use the OAuth authorization protocol – where you will need to present a good authentication experience for your users. Doing this for Office add-ins can be a bit challenging.

Office add-ins have no concept of identity (except for Outlook add-ins) and require the domain of all the pages you want to display (within the add-in) to be registered beforehand in your manifest file. So if we deal with federated users, it will be impossible to list all of the potential domains.

Because of that, we must own the authentication experience and most likely make it popup-based. However, popups bring another set of challenges in terms of communication between the popup and the add-in.

In this post I will be using ASP.NET SignalR (http://signalr.net/) and Active Directory Authentication Library (https://azure.microsoft.com/sv-se/documentation/articles/active-directory-authentication-libraries/) in my ASP.NET MVC project to create a good authorization flow for the Office 365 APIs in my Office add-in.

Get the frameworks
You can use the NuGet Package Manager in Visual Studio to install ASP.NET SignalR and ADAL (Active Directory Authentication Library for short).

nugets

Now in order to use SignalR in your project, you will need to map it. If you don’t already have an OWIN Startup class – create one by adding a new file to your ASP.NET project.

owin

Call the MapSignalR extension method in the Startup class like so:

Define your authentication logic
I created a helper class to hold the information about client credentials, redirect URIs, resources, etc. Create any classes or other utilities in your taste that helps you to manage the data and logic needed to complete the authentication flow.

Pass down any details required in your front-end via the Controller, for instance using the ViewData dictionary.

Creating the view
Build a View for your Controller and make sure that you include the SignalR JavaScript libraries (jQuery is required by SignalR) – then hook up some JavaScript logic to trigger the authentication flow.

The first thing is to extract the details needed from the ViewData dictionary and then set the Office.initialize method in order to initialize the Office.js library.

Now go ahead and configure the SignalR connection:

  • Define the function that we can call from the server-side when the tokens are ready
  • Start the connection
  • Get the connection ID – so that we know which client to talk to

Everything is done via a SignalR Hub, which we need to create on the server-side. Add a new class to your project, name it something suitable and derive from the SignalR Hub class.

Be sure to use the same name (of the SignalR Hub) in your JavaScript. In my C# class I used the name “AuthorizationHub” – so I will use “authorizationHub” in my JavaScript.

Also pay attention to the function name, in order to call it from the server-side you will need to use the same name – “tokenReceived” in my case.

Finally hook up any event handlers to show the popup. Ideally you want to trigger this from an onclicked event – because this is a trusted event (user invoked) and web browsers will not block your popup.

Notice that I’m replacing the signalrid part of the URI with the actual connection ID. We need to catch it on the server-side in order to know which client to talk to.

This is my final .cshtml file:

Handling the authentication response (authorization code)
If you look at my helper class, I make sure to redirect any authorization responses (with the redirect parameter) to a new Controller (TokenController). This Controller will be in charge of doing a couple of things:

  • Get the connection ID (SignalR)
  • Get the authorization code
  • Exchange the authorization code for Azure Active Directory tokens
  • Call the tokenReceived function on the client-side (with the connection ID)

Because I’m authenticating for the Office 365 APIs, I can use ADAL to exchange the authorization code for tokens – as the Office 365 APIs only accept Azure Active Directory tokens.

Depending on the service you are building for – your logic and order of things may be different.

When we call the TokenReceived method – the client-side will be notified and run the JavaScript function (tokenReceived). We will pass the access token as a parameter (token) to that particular function.

At this point we can return a View, but since we’re all done at this point – I can simply present the user with the following experience. It should just close the popup right away.

Running this will present me with the OAuth experience provided by Azure Active Directory. Everything will be shown in a popup that I customized with the specs parameter in the window.open (http://www.w3schools.com/jsref/met_win_open.asp) function.

As expected by the OAuth flow – if the authentication is successful, I will be redirected to the provided redirect URI with an authorization code. When this happens, the Token Controller will respond, exchange the authorization code for tokens and pass it to the Office add-in.

flow2

That’s it! Using SignalR to architecture your authentication flow is very reliable, because we leverage web sockets (avoiding troubles with browser security zones). With popups we can also handle any domain potentially served by the authorization endpoint – which makes for a very robust experience.

Here is a GitHub project that does just about the same thing – using ASP.NET SignalR and ASP.MVC:
https://github.com/OfficeDev/O365-API-from-Office-Addin

-Simon Jäger