Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to get access to onedrive content

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:

  • People.Read - Delegated
  • Sites.ReadWrite.All - Delegated
  • Sites.ReadWrite.All - Application
  • Tasks.ReadWrite - Delegated
  • User.Export.All -Delegated
  • User.Export.All - Application
  • User.Invite.All - Delegated
  • User.Invite.All - Application
  • User.Read - Delegated
  • User.Read.All - Delegated
  • User.Read.All - Application
  • User.ReadBasic.All - Delegated
  • User.ReadWrite - Delegated
  • User.ReadWrite.All - Delegated
  • User.ReadWrite.All - Application
  • offline_access - Delegated
  • openid - Delegated
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"
    }
  }
}
like image 326
sion005 Avatar asked Sep 17 '25 07:09

sion005


1 Answers

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.

like image 96
Marc LaFleur Avatar answered Sep 21 '25 13:09

Marc LaFleur