I'm developing an application where I need to use Microsoft Graph to access the files on a OneDrive for Business. I created a web app on Azure and I manage to get the authentication token and I'm able to retrieve the user information with https://graph.microsoft.com/v1.0/me
. However, if I try to get the content of the OneDrive with https://graph.microsoft.com/v1.0/me/drive/root/children
I get an access denied error.
I already checked on Graph Explorer and I'm able to get the result for the query without any issues. For my web app, I'm using the following Graph permissions:
public async Task<string> GetTokenAsync()
{
HttpResponseMessage resp;
using(var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Accept
.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
var req = new HttpRequestMessage(HttpMethod.Post,
$"https://login.microsoftonline.com/{tenant}/oauth2/token/");
req.Content = new FormUrlEncodedContent(new Dictionary<string, string>
{ { "grant_type", "password" },
{ "client_id", clientId },
{ "client_secret", clientSecret },
{ "resource", "https://graph.microsoft.com" },
{ "username", username },
{ "password", password },
{ "scope", "https%3A%2F%2Fgraph.microsoft.com%2F.default" }
});
resp = await httpClient.SendAsync(req);
string content = await resp.Content.ReadAsStringAsync();
var jsonObj = new JavaScriptSerializer().Deserialize<dynamic>(content);
string token = jsonObj["access_token"];
Console.WriteLine(token);
return token;
}
}
public async Task<string> SendGraphRequest(string requestUrl)
{
using(HttpClient httpClient = new HttpClient())
{
// Set up the HTTP GET request
HttpRequestMessage apiRequest =
new HttpRequestMessage(HttpMethod.Get, requestUrl);
apiRequest.Headers.UserAgent
.Add(new ProductInfoHeaderValue("OAuthStarter", "2.0"));
apiRequest.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", await GetTokenAsync());
// Send the request and return the response
HttpResponseMessage response = await httpClient.SendAsync(apiRequest);
var s = response.Content.ReadAsStringAsync();
Console.WriteLine(s.Result);
return s.Result;
}
}
My call for the graph api is:
SendGraphRequest("https://graph.microsoft.com/v1.0/me/drive").Wait();
The result I get from this is:
{
"error": {
"code": "accessDenied",
"message": "There has been an error authenticating the request.",
"innerError": {
"request-id": "request-id",
"date": "2019-09-24T11:03:29"
}
}
}
After almost two week trying to fix this issue I realised that the problem was not the code, but the azure configuration. I was under the assumption that if a web app is installed on the account of the administrator of the active directory, that all users on that active directory would be capable of using the same web app to access their respective One Drive accounts. Unfortunately this is not the case, if a user (not the administrator) tries to use the web app to access One Drive, the only thing he or she will be capable of reaching is their account information, with no access to files. In order to use the graph api to access the files, the web app needs to be installed on their respective active directories.