Simplifying O365 Outlook client Add-In Authorization without C#

In this article I will demonstrate a simple method for getting an Authorization into and Outlook Add-in without writing any C# code. I will also highlight some of the problems involved and how the solution elegantly overcomes this.

Introduction

In the previous article we looked at how the How the example O365 Authorized CORS application works and in that example is a location.href change which works just fine within a web browser, but fails badly as an outlook client Add-in.

When the example CORS application is packaged and deployed as a client Add-in it appears to work until you click the “Get Token Button”. The location.href change causes an Internet Explorer window to open, where you can log in……but the end result is you being in an Internet Explorer Window and the token is not in the Outlook Add-in.

A recognized way to solve this issue 

Simon Jaeger has written a number of excellent articles on how to create Outlook Add-ins through Visual Studio and writing some C#

http://simonjaeger.com/developing-outlook-add-ins-where-to-integrate-and-what-you-can-do/

http://simonjaeger.com/building-a-good-authentication-flow-in-an-office-add-in/

The guys in my team tell me that those are a pretty sweet solution to the problem, but my problem is I am not a C# developer and have no desire to become one.

What Simon’s code did do though, was was to inspire me to try something different.

Solving the problem without C#

As I understand it Simon’s example opens an authentication window and then passes the authentication token back to the Add-In via SignalR

 // Show prompt in a new window
    window.open(redirectUri.replace("signalrid", signalrId), "",
        "menubar=0,location=1,resizable=1,scrollbars=0,status=0,toolbar=0,width=550,height=600");

But it struck me that the window.open opens the possibility for the open window to communicate with the opener. (Yeah I know that’s a dumb sentence but it is accurate).

So I put it to the test. I created a button on my sample index.html and made the deployment as an add-in

c1

The code on the button – dead simple – open the window on itself (it really doesn’t matter which site)

<button onClick="window.open('https://xomino365.azurewebsites.net/o365/index.html')">Open Window</button>

Looking at the open window we can bring up developer tools and use the console to test if window.opener is null.

c3

and it isn’t.

So then let’s do a test – let’s see if we can manually stick a value back into the opener……and it did !!

c4

Well in that case we are all sorted !!

Modifying the example code

I am modifying my existing code for the sake of a consistent story, this is not how you would do it in production.

  • If the index.html opens and window.opener is not null I call the function to requestToken() automatically.
  • The page reloads
  • If the page loads detects that we have a token, and we have a window.opener, it
    • Sends the token back to the Outlook client Add-In
    • Hides all the buttons
    • Clicks the Make CORS Request button automatically
    • Closes the popped up window
            if (window.opener){
                window.opener.document.getElementById("TxtOauthToken").value = token;
                window.opener.document.getElementById("doCors").style.visibility = "visible";
                window.opener.document.getElementById("doCors").click()
                window.opener.document.getElementById("getToken").style.display = "none";
                window.close()
            }

And that’s it – the user either sees a quick popup and then the Add-In gets the data from SharePoint. If they have not checked the “keep me logged in” box, or have had their login expire, they see a log in screen where they authenticate with O365 SharePoint, the window then closes and runs in the Add-In.

c5

Conclusion

In this article we have seen how to use a window.open from within our Outlook Add-in to be able to create an Authorization token which can be passed back to the Add-In and used to get Cross-Domain SharePoint data from O365.

In a future article I will streamline this code to create something which can be used for just authorization and is not the same webpage as the Add-In.

 

PS

If you have never done this before you may be prompted with the following dialog – which MAY come up in the background as well. You need to (and tell your users to ) check the box and Allow this in the future.

c2

PPS

I also discovered that you can use WebSockets to transfer data “into” the Outlook Client Add-In. This turned out to be unnecessarily complex and raises some security concerns – but – makes for some excellent ideas for future Add-In functionality ideas.

Advertisements

4 thoughts on “Simplifying O365 Outlook client Add-In Authorization without C#

  1. Unfortunately, I don’t think this solves the problem. The main point of popping open the authentication dialog (imo) is to be able to pair an identity token with an actual user account since the identity token, sadly despite its name, does not actually contain identifying information. And if you were to send the identifying info (eg email address) through your message back to the opener this would be a huge security information.

    The only way we’ve found to solve this is to pass the identity token along with the popped up window through the server side auth flow and save it to the appropriate user. Back in the add-in you have to ping an api with the identity token and see if it matches a user account. If your add-in (like ours) uses standard sessions for its functionality, you’ll also need to create a session at that time. You could also do it as a separate web request but there isn’t a point unless you were an ulta purist about REST standards or something….

    Like

  2. Thanks for the comment 🙂

    The article is 18 months old – at the time there was no other good way of getting an OAuth token into an Add-In and there was a convoluted websockets backend solution being proposed by MS.

    The point of Authorization is not to get the user credentials – I want to act on their behalf and pull data from Azure/O365 getting their email address would be one use case but not the only one.

    I agree that is another call to get the id from the graph but that does go beyond the extent of the blog post.

    Thanks again 🙂

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s