Bridge Communications

Saturday, September 30, 2017

Getting Started with Microsoft Teams Tabs - Part 4 #MicrosoftTeams

Microsoft Teams is a chat-based collaboration tool that is part of the Office 365 suite of services. Teams enables local and co-workers to work together and collaborate through a common work-space, using features such as team chat, one-on-one chat and document collaboration.

Authentication in Tabs

Authentication in Teams tabs is the same thing as authentication to the o365 portal, or any of it's children.  In fact if your o365 portal token is still alive, you'll never even see the sign in page in your teams tab app, it just passes through.  In the case the above scenario doesn't work you are going to need to be able to handle authentication.  No big deal right?  Well...

There is one big thing that can gum up the works here, your teams tab page is running in an iframe, and there is some debate as to whether or not it will work as you'd expect.  Here I'll quote the teams developer page directly.

The tab configuration and content pages run in iframes. Azure Active Directory (Azure AD), and other identity providers that you may use, do not usually allow their sign-in and consent pages to be hosted within an iframe. Because of this, your app needs to authenticate the user in a pop-up window. You must use the Microsoft Teams JavaScript library to do this, so that it works successfully in both the web and desktop apps for Microsoft Teams.

Whenever you see the words "do not usually" you should probably plan to code around this in the proper way.  Fortunately the teams js api has some code to help us.  Here are the 7 steps the developer page recommends for logging in, my commentary will follow.

  1. Add UI to your configuration or content page to enable the user to sign in when necessary. You should not drive the authentication pop-up without user action, because this is likely to trigger the browser's pop-up blocker.
  2. Add the domain of your authentication URL to the validDomains section of the manifest. Failure to do so might result in an empty pop-up.
  3. You can get user context information to help build authentication requests and URLs. For example, you can use the user's name (upn) as the login_hint value for Azure AD sign-in, which means the user might need to type less, or even that sign-in completes with no user action at all. Note that you should not use this context directly as proof of identity. For example, an attacker could load your page in a "malicious browser" and provide it with any information they want.
  4. When the user selects to sign in, call microsoftTeams.authentication.authenticate({url: <auth URL>, width: <width>, height: <height>, successCallback: <successCallback>, failureCallback: <failureCallback>}).
    This launches the pop-up window in which the authorization should occur. This page should be hosted on your domain and listed in the validDomains section of the manifest. Within this authorization page, you should redirect to your identity provider, so the user can sign in. After the user completes authentication, the pop-up window is redirected to the callback page you specified for your app.
  5. In your app's callback page, call microsoftTeams.authentication.notifySuccess() or microsoftTeams.authentication.notifyFailure().
    This results in a callback to the successCallback or failureCallback function that you registered in step 4, inside the original configuration or content page.
  6. If successful, you can refresh or reload the page and show the configuration or content relevant to the now-authenticated user. If authentication fails, display an error message.
  7. Your app can set its own session cookie in the usual way so that the user need not sign in again when they return to your tab on the current device.

Ok as I try to understand and explain this, here are a couple things to note;

1.  In my tests this method is fraught with peril.  Having to do make a separate button to initiate a login in today's token passing SSO world is a giant step backward.

2.  Changing the azure ad login to allow auth from an iframe hosted in teams would provide a much better experience, and allow existing web apps to not have to be re-written for this clunky authentication method.

3.  Every device the user potentially tries to open your tab on could wind up with a different experience.  A new browser window for a login is a completely different experience on a Windows PC and an android phone.

Final thoughts;

I would completely start over with this process.  Really if you are using Azure AD as the auth source, which let's face it > 90% of the tabs are going to, because they want access to MS graph which can then see the corresponding teams data from the context, then why have an option when you can get the current teams token from the context and use it.  The only real time this wouldn't be enough is if you wanted to extended admin consent type scopes anyway, and if that was the case, go back to point 2 above.

Happy coding,

Doug Routledge,  Teams, Skype for Business, SQL, Exchange, UC, 
Full Stack Developer  BridgeOC Bridge Operator Console
Twitter - @droutledge @ndbridge