When our Azure web service calls Graph APIs on behalf of an external user, they fail with a 401 unauthorized: "There has been an error authenticating the request." A specific example is when we try to get all of the teams that the current user has access to using this call:
https://graph.microsoft.com/v1.0/me/joinedTeams?$select=id,displayName
We have discovered that calling a SharePoint API first for external users will allow us to then call the Graph APIs without 401 errors. Alternatively, the external user can login to SharePoint directly in a browser and subsequent Graph calls for that user will work. This "touch" of the SharePoint API appears to unlock use of the Graph API. Here's some code:
var sitesQueryUrl = $"{hostPath}/sites/{Constants.ExternalUserSupportSite}/_api/search/query?querytext='contentclass:STS_Site'&selectproperties='Path'&refinementfilters='SPSiteUrl:(\"{hostPath}/sites/*\")'";
The hostPath variable is the root site of the customer's SharePoint Online tenant.
Simply performing this query seems to be enough to allow the Graph calls to work for all of the sites that the external user has access to.
A follow-on problem is knowing a SharePoint resource that the external user should be able to access. To solve this issue we ask our customers to create a site collection with a "magic name" (Constants.ExternalUserSupportSite in the code above) and allow external users access to it. The site collection can be entirely empty, it's just there to be a known resource with a known URL. This is not an ideal work around for us in the long run.
We’ve checked the external user's token is valid and contains all the proper delegated permission scopes. Additionally, everything is configured corretcly in Azure AD and SharePoint to allow external user access.
This thread describes the same issue: https://github.com/OneDrive/onedrive-api-docs/issues/1039