I'm having a problem using Microsoft Graph for external users (i.e. guests invited to the tenant) in my project.
- Angular 8 application for the front end
- NestJs for the backend
- Delegated permissions added to the App Registration for Sites.ReadWrite.All (Admin Consent is given)
The Token is passed to the backend application where I make another call to the Microsoft auth endpoint to get another access_token "on behalf of the user" which I then use to create my graph client.
async getClient(request: Request): Promise<Client> {
const accessToken = await this.tokenProvider.getAccessTokenOnBehalfOfUser(request);
return Client.init({
authProvider: done => {
done(null, accessToken);
},
});
}
async getAccessTokenOnBehalfOfUser(request: Request): Promise<string> {
const loginToken = request.headers['authorization'].replace('Bearer ', '');
const headers = { 'Content-Type': 'application/x-www-form-urlencoded' };
const body = new URLSearchParams();
body.set('grant_type', 'urn:ietf:params:oauth:grant-type:jwt-bearer');
body.set('client_id', process.env.OIDC_CLIENT_ID);
body.set('client_secret', process.env.OIDC_CLIENT_SECRET);
body.set('scope', 'openid');
body.set('assertion', loginToken);
body.set('requested_token_use', 'on_behalf_of');
const response = await this.httpService
.post(`https://login.microsoftonline.com/${process.env.OIDC_TENANT_ID}/oauth2/v2.0/token`, body, {
headers: headers,
})
.toPromise();
return response.data['access_token'];
}
async getFilesByFolerPath(folderPath: string, client: Client) {
try {
return await client.api(`/${SITES}/${this.siteId}/drive/${ROOT}:/${folderPath}:/${CHILDREN}?${EXPAND_LISTITEM}`).get();
} catch (error) {
const x = error;
}
}
Problem:
Here's the weird part. When I am logged in as an external user, I get a 403
error response from getFilesByFolderPath
. However, when I go to the SharePoint site it's trying to reach separately, I have access and can see all the documents, files, etc. After I have opened SharePoint, the call to Microsoft Graph works.
NOTE: I even log into SharePoint on a separate browser (even inside a different VM) just to make sure it's not caching a token.)
However, after a period of time (~1 hour), the Graph call stops working again. I then need to go to SharePoint and refresh any page for it to restore access.
For internal AAD users, this call works 100% of the time. Looking at my access token it has all the required permissions etc.
Wondering has anyone any ideas on this?
Error thrown by the Graph doesn't have much information in it:
Update
I ran the request in postman and the response headers had this error code and details:
X-MSDAVEXT_Error →917656; Access denied.
Before opening files in this location, you must first browse to the web site and select the option to login automatically.
There must be a setting in the Admin portal for Office365/SharePoint that can help with this situation for External members to the AAD.