Невозможно получить доступ к содержимому onedrive - PullRequest
2 голосов
/ 24 сентября 2019

Я разрабатываю приложение, в котором мне нужно использовать Microsoft Graph для доступа к файлам в OneDrive для бизнеса.Я создал веб-приложение в Azure, и мне удается получить маркер аутентификации, и я могу получить информацию о пользователе с помощью https://graph.microsoft.com/v1.0/me.Однако, если я пытаюсь получить содержимое OneDrive с помощью https://graph.microsoft.com/v1.0/me/drive/root/children, я получаю сообщение об ошибке отказа в доступе.

Я уже проверил в Graph Explorer и смог получить результат для запроса без каких-либо проблем.,Для своего веб-приложения я использую следующие разрешения Graph:

  • People.Read - делегированный
  • Sites.ReadWrite.All - делегированный
  • Sites.ReadWrite.All - Приложение
  • Tasks.ReadWrite - Делегировано
  • User.Export.All -Delegated
  • User.Export.All - Приложение
  • User.Invite.All - делегирован
  • User.Invite.All - приложение
  • User.Read - делегирован
  • User.Read.All - делегирован
  • User.Read.All - приложение
  • User.ReadBasic.All - делегировано
  • User.ReadWrite - делегировано
  • User.ReadWrite.All - делегировано
  • User.ReadWrite.All - Приложение
  • offline_access - делегировано
  • openid - делегировано
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;
    }
}

Мой вызов для API api:

SendGraphRequest("https://graph.microsoft.com/v1.0/me/drive").Wait();

В результате я получаю:

{
  "error": {
    "code": "accessDenied",
    "message": "There has been an error authenticating the request.",
    "innerError": {
      "request-id": "request-id",
      "date": "2019-09-24T11:03:29"
    }
  }
}

Ответы [ 2 ]

1 голос
/ 25 сентября 2019

Вы слишком сильно зарезервировали свои возможности здесь.Например, вам не нужны обе области чтения и чтения.Вы также запрашиваете некоторые области применения, но используете грант OAuth-пароля, который будет работать только с делегированными областями (вы не можете смешать две).

Я бы порекомендовал объединить ваши области действия со следующими делегированными разрешениями:

openid User.ReadWrite User.ReadBasic.All Files.ReadWrite.All
People.Read Sites.ReadWrite.All Tasks.ReadWrite offline_access

Обратите внимание, что Sites.ReadWrite.All немного отличается от Files.ReadWrite.All.Один касается SharePoint, другой OneDrive.

0 голосов
/ 27 сентября 2019

После почти двух недель попыток решить эту проблему я понял, что проблема была не в коде, а в конфигурации Azure.Я предполагал, что если веб-приложение установлено в учетной записи администратора активного каталога, то все пользователи в этом активном каталоге смогут использовать одно и то же веб-приложение для доступа к соответствующим учетным записям One Drive.К сожалению, это не тот случай, если пользователь (а не администратор) пытается использовать веб-приложение для доступа к One Drive, единственное, что он или она сможет получить - это данные своей учетной записи без доступа к файлам.Чтобы использовать график api для доступа к файлам, необходимо установить веб-приложение в соответствующие им активные каталоги.

...