Microsoft Graph API content 401 Unauthorized

2.7k views Asked by At

I am authenticating with client id and secret.

String url = String.format("https://login.microsoftonline.com/%s/oauth2/token", tenantContext);
AuthenticationContext context = new AuthenticationContext(url, true, ForkJoinPool.commonPool());
AuthenticationResult result = context.acquireToken("https://graph.microsoft.com", new ClientCredential(clientId, clientSecret), null).get();     
String token = result.getAccessTokenType() + " " + result.getAccessToken();

My application has all the permission boxes ticked and with the above token I can list users and traverse their drives and folders. I can access content from https://graph.microsoft.com/v1.0/drives/%s/items/%s/content which returns another URL in the Location header. However when I try to get that URL it returns 401 Unauthorized.

3

There are 3 answers

1
RasmusW On

Is the other URL also on graph.microsoft.com? If not, then you need to get a new authentication token for that URL, and then use it in your download requests.

Just like you are already doing with graph.microsoft.com, but with the other server name:

AuthenticationResult result = context.acquireToken("https://onedrive-server-name", new ClientCredential(clientId, clientSecret), null).get();     
1
Bartosz J On

Make sure you have added following permission: Files.ReadAll or Files.ReadWriteAll Revoke the app access and try again (https://portal.office.com/account/#apps)

However the "@microsoft.graph.downloadUrl" should work out of box, maybe you disabled offline access in library settings?

0
Alastair On

I succeeded in downloading content from users by logging in an admin user and getting a refresh token obtained from app authentication using Azure AD

The refresh token can then be redeemed using adal4j:

AuthenticationContext context = new AuthenticationContext(url, true, ForkJoinPool.commonPool());
AuthenticationResult result = context.acquireTokenByRefreshToken(refreshToken, new ClientCredential(clientId, clientSecret), "https://graph.microsoft.com", null).get();
String token = result.getAccessTokenType() + " " + result.getAccessToken();

Using this access token you can get file content via: https://graph.microsoft.com/v1.0/drives/{driveid}/items/{itemid}/content

There is one vital extra step - the admin user must be added as a site collection owner for the user whose content you are accessing. This is described in this blog.