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"
}
}
}
You're way over-provisioning your scopes here. You don't need both Read and ReadWrite scopes for example. You're also requesting some Application scopes but using the OAuth Password grant which will only work with Delegated scopes (you can't mix the two).
I would recommend pairing down your scopes to the following Delegated permissions:
openid
User.ReadWrite
User.ReadBasic.All
Files.ReadWrite.All
People.Read
Sites.ReadWrite.All
Tasks.ReadWrite
offline_access
Note that Sites.ReadWrite.All
is a bit different than Files.ReadWrite.All
. One concerns SharePoint, the other OneDrive.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With