I've been tasked to make this happen: Outlook Add-in with OIDC authentication to a non-microsoft API.
The task pane will be written in Angular, and I'm already using angular-auth-oidc-client
as the client-side OIDC auth package for other projects, so I'm thinking I'll use it here, too.
I've gotten to the point of being able to load the Outlook add-in and it uses Office.UI.displayDialogAsync
to open a dialog window for user to sign in, and it uses Office.UI.messageParent
to send the access token to the task pane.
But then what? Once I have the access token on the task pane, what do I do with it? I have to manually store and keep track of expiration, and manually trigger a refresh? There's no way to load the access token into the client auth package on the task pane.
I'm runing into an issue of documentation, as I can't find any samples of a scenario like mine. All the documentation says is:
Your code in the dialog box window sends the access token to the host window either by using messageParent to send the stringified access token or by storing the access token where the host window can retrieve it (and using messageParent to tell the host window that the token is available). The token has a time limit, but while it lasts, the host window can use it to directly access the user's resources without any further prompting.
Here it says don't store access tokens, but I guess that's just in the context of using SSO? Which is another point of confusion. Is Microsoft calling an Office-specific authentication scheme "SSO", like, the generic term for external authentication? This makes all the information out there bleed together so it's hard to discern SSO™ from SSO.
The main questions are:
- What do I do with the access token once it's on the task pane?
- How do I deal with token expiration in this regime?
- Are there any samples that show authentication to something other than a microsoft IDP?
Alright, folks. After a couple days non-stop of working on this, I've figured out how to make it all work nicely.
So. Using
angular-auth-oidc-client
, here's the code to make it all work.app.module.ts:
Take note of
callbackUrl
supplied to redirectUrl.app.component.ts:
Now, once the user logs in in the Office dialog window, it will redirect to
callbackUrl
with query params including code=blahblah. All you need to do is to send that URL back to the parent window like this:html at
callbackUrl
:And that's it. It seems to be a pretty decent solution without resorting to any questionable hacks or anything.
Time for whiskey.
Edit
Turns out there's a missing piece. Cookies are being blocked, at least on Chrome, so if the user wants to log out, IdentityServer4 won't have enough info to properly log out.
This describes how to get third party cookies to work in an add-in. What wasn't clear from that doc is that for
document.requestStorageAccess
to not be automatically rejected, it must be called within the context of a user interaction, like a click or a tap. See hereSo here's the new process. HTML template:
And code:
Now, user log off can play nice with IdentityServer.