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?
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+Teamsfxto 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.