Search code examples
oauth-2.0microsoft-teamsteams-toolkitmicrosoft-teams-js

User prompted for entering password again(even after being logged in Teams application) in Teams personal app if we use OAuth code flow


We have created a Teams personal app which is already published in the Teams App Store. The authentication mechanism we follow is based on OAuth code flow, where we use authentication.authenticate() function provided by Teams js sdk to open login with Microsoft page. We specify all the required parameters like tenant id, client_id etc, along with login_hint. This opens up a new window with login.microsoft.com url and the user gets authenticated directly in Teams desktop and browser (Windows and Linux) i.e, the window which is opened up closes by it self and user doesn't need to enter his credentials again.

But in Mac devices and mobile devices, the window which is opened up doesn't close by itself and asks user to enter password again in spite of being logged-in inside Teams application.

How can we avoid user interaction to get the oauth code in Mac and mobile devices?

We do have methods to get AD token silently but getting AD token with a lot of scope in client side code and sending new token every time to backend when it expires is not a good idea we feel. Is there any way we can get oauth code inside Teams personal app silently without user interaction? Or is there any other way through which, we handle this scenario?


Solution

  • If I understand your scenario correctly based on the follow-up details (thanks for providing them!), the canonical way for Teams apps to handle this is to use the SSO flow enabled by teams-js in conjunction with the on-behalf-of (OBO) flow. You can read the full details about leveraging SSO at the SSO overview page and then see how to extend it to call other endpoints (like MS Graph) using the pattern described on the extend tab app page.

    Overview of the flow:

    1. Your Teams app calls authentication.getAuthToken. This function will return an authentication token, issued to Teams, for the resource you specify in the webApplicationInfo section of your app manifest. This resource should be your backend/middle-tier service.
    2. Your Teams app sends this token to your backend.
    3. Your backend executes the OBO flow to exchange that token for a new token. This new token is issued to your service for the resources you actually want to access (e.g. Calendar.Read in your example). The output of this OBO flow is both that access token as well as a refresh token. If the access token expires, your backend can use the refresh token to acquire another one.
    4. Your backend uses that token to access the desired resource.

    Eventually the refresh token will also expire. In this case, your backend will need a new token from your client (repeating the above steps). However, this should be infrequent.

    When using this flow, the users of your Teams app should normally not see any authentication/login UI (there may be some one-time or infrequent UI interrupts due to an initial consent prompt or other prompts (e.g. multi-factor auth) depending on the configuration of the tenant). No client secret or other sensitive information should need to be stored on the client. Finally, while all tokens will eventually expire, leveraging the refresh token received as part of the OBO flow will minimize the need to constantly be retrieving and sending tokens from the client.