Microsoft Graph Toolkit - TeamsFxProvider - Getting empty token on iOS devices

131 Views Asked by At

I am building a Teams tab app using React, MGT, and using the TeamsFxProvider to call graph API on behalf of the user. The auth setup is like so (mostly from the example project created by teams toolkit):

    const { loading: credLoading, teamsUserCredential } = useTeamsUserCredential({
        initiateLoginEndpoint: config.initiateLoginEndpoint!,
        clientId: config.clientId!
    });

    useEffect(() => {
        if (!credLoading) {
            const provider = new TeamsFxProvider(teamsUserCredential!, userScopes);
            Providers.globalProvider = provider;

            // Attempt to get token silently
            teamsUserCredential
                .getToken(userScopes)
                .then(() => Providers.globalProvider.setState(ProviderState.SignedIn))
                .catch(() => {
                    // If silent token fails then interactive login required
                    setLoginNeeded(true);
                })
        }
    }, [credLoading, teamsUserCredential]);

    if (loginNeeded)
        return <Login /> // Our component for logging in interactively etc

This seems to work correctly in signing in silently when possible and prompting an interactive login when needed.

In a graph api service I am getting a graph client like this: const client = Providers.globalProvider.graph; which seems to work fine for calling the graph API.

All of this is working fine in the teams desktop client and teams web (both old and new teams), and in the android teams app.

However on iOS I am having issues. First of all the user gets forced to log in interactively every time the app opens, and secondly the graph calls are failing. On investigation it seems the graph calls return 401 becuase the token provided here is empty (I can see on the HTTP request "Authorization: Bearer ".

I believe behind the scenes the globalProvider.graph client calls Providers.globalProvider.getAccessToken() which we have verified is returning an empty string on iOS for some reason.

This is really seeming like an issue somewhere in MGT or TeamsFx as it works fine in all other places, but I am just wondering if anyone has any ideas or if there are known issues with iOS?

Edit: with a bit more testing I believe this is basically one issue in that the provider is always failing to acquire a token silently, this would explain the login prompts and why the token returns empty. But I don't know why this would happen solely on iOS, again this seems to point to an iOS specific bug?

1

There are 1 best solutions below

1
SLdragon On

This is a known issue on the iOS platform where limitations exist for the WebView to persist tokens.

Relevant discussions can be found at:

https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/3329

https://github.com/OfficeDev/TeamsFx/issues/7574

https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/5617

Since the MSAL library does not officially support the iOS platform, we suggest using the On-Behalf-Of (OBO) flow for token exchange to solve this issue on mobile platform.

An example of using Azure APIM + ProxyProvider + Teamsfx to exchange tokens for MGT can be found here:

https://github.com/OfficeDev/TeamsFx-Samples/tree/dev/sso-enabled-tab-via-apim-proxy

You can clone this sample and hit F5 to debug and view this sample.