Usar a API do OneDrive sem interação do usuário, como um programa em lotes (versão do .NET C#) (sem bibliotecas de uso adicionais)

Página atualizada :
Data de criação de página :

Ambiente operacional

Visual Studio
  • Visual Studio 2022
.REDE
  • .NET 8
API de Autenticação da Microsoft
  • 2.0 OAuth 2
Microsoft OneDrive API
  • 1.0
Tipos de contas da Microsoft
  • Conta corporativa ou de estudante

Pré-requisitos

Visual Studio
  • Uma das versões
.REDE
  • Uma das versões
API de Autenticação da Microsoft
  • 2.0 OAuth 2
Microsoft OneDrive API
  • 1.0
Tipos de contas da Microsoft
  • Conta corporativa ou de estudante

Sobre o objetivo deste evento

Agora você usará as APIs do OneDrive para prepará-lo para carregar e baixar arquivos programaticamente para o OneDrive. Neste artigo, veremos o que você pode fazer com a API do OneDrive, portanto, não entraremos no que você pode fazer com a API do OneDrive. No entanto, desde que você possa se conectar, você pode ler a documentação da API e aplicá-la depois disso.

Como executar o programa

O acesso ao OneDrive não depende da forma do programa, como um aplicativo Web, um aplicativo da área de trabalho ou um aplicativo de console, e pode ser executado por vários programas. Nesse caso, criaremos um aplicativo de console e o executaremos automaticamente sem nenhuma operação do usuário.

Quais são os diferentes tipos de contas da Microsoft?

Se você já criou uma conta da Microsoft, provavelmente já a viu. Existem dois tipos principais de contas da Microsoft: contas pessoais da Microsoft e contas corporativas ou de estudante. O OneDrive está vinculado a uma conta da Microsoft, mas o tipo de OneDrive varia um pouco dependendo do tipo de conta listado acima.

Por enquanto, a API do OneDrive pode ser usada com os dois tipos de contas acima. Neste programa na forma de "criado como um aplicativo de console e executado sem operação do usuário", Observe que ele só pode ser usado com uma conta da Microsoft na conta "Conta corporativa ou de estudante". Isso se deve a diferenças nos métodos de autenticação.

Sobre o método de autenticação

Primeiro, você deve se autenticar para acessar o OneDrive programaticamente. Conforme mencionado acima, qualquer programa pode acessar o OneDrive, mas a autenticação para se conectar à API depende de como o programa está sendo executado. Aplicativos Web e aplicativos da área de trabalho podem ser autenticados pela interação do usuário. Como o usuário não pode operá-lo em um aplicativo de console executado em segundo plano, o método de autenticação também é diferente do acima.

Não sei o motivo detalhado porque não consegui pesquisar, mas se me vier à mente, parece ser devido à segurança e ao gerenciamento de contas. Só posso dizer que isso já é uma especificação, portanto, se você deseja acessar programaticamente o OneDrive associado a uma "conta pessoal da Microsoft", Acho que não há escolha a não ser usar um programa diferente de um programa que seja executado em segundo plano ou executar um aplicativo de console com um método de autenticação que inclua operações do usuário.

Não usaremos a biblioteca para acessar a API do OneDrive no momento

O acesso à API do OneDrive é relativamente fácil de manipular usando uma biblioteca chamada "Microsoft Graph". Nesse caso, usaremos o método de acessar diretamente a URL da API e executá-la. É um pouco complicado, mas como não usa uma biblioteca, tem a vantagem de que non-.NET programas podem acessar a API do OneDrive da mesma maneira. Também evita a desvantagem de que o código seja alterado devido a diferentes versões da biblioteca.

Mostraremos como usar o Microsoft Graph em outra dica.

pré-condição

  • Você tem uma conta da Microsoft para uma conta corporativa ou de estudante
  • Você pode usar o OneDrive associado à conta da Microsoft listada acima (por exemplo, OneDrive Business)
  • Visual Studio 2022 instalado

Configurar seu aplicativo para acessar sua conta da Microsoft ou OneDrive no Azure

Faça logon no Azure na seguinte URL:

No campo de pesquisa acima, digite "registros de aplicativos" e selecione-o.

Clique em Novo registro.

O conteúdo do "Nome" é arbitrário. Insira um nome descritivo.

Selecione um "Tipo de conta com suporte" diferente de "Somente contas pessoais da Microsoft". Isso ocorre porque, como mencionado acima, essa autenticação só pode ser usada com contas que pertencem a uma organização. Nesse caso, selecionamos "Contas em qualquer diretório organizacional (qualquer locatário do Microsoft Entra ID - multilocatário) e contas pessoais da Microsoft (Skype, Xbox etc.)".

Você não precisa inserir o "URI de redirecionamento" porque ele não será usado desta vez.

Quando terminar, clique no botão "Registrar".

Você será levado para a página de resumo do registro do aplicativo que criou, portanto, copie a ID do aplicativo (cliente) e a ID do diretório (locatário). Você usará esse valor mais tarde.

Selecione "Certificados e segredos" na categoria de gerenciamento no menu à esquerda e certifique-se de que "Segredos do cliente" esteja selecionado na guia do meio. Clique em Novo Segredo do Cliente.

Inserir uma descrição é opcional. Se você quiser continuar usando, inclua uma explicação que explique claramente a finalidade do uso.

A "data de expiração" é o período de tempo em que esse segredo do cliente é válido. Como é para fins de teste desta vez, são 90 dias, mas defina-o de acordo com a finalidade de uso.

Quando você cria um segredo do cliente, ele é adicionado à lista. Neste, usaremos o valor na coluna "Valor", então copie-o. Observe que esse valor não pode ser copiado posteriormente.

Em seguida, selecione "Permissões de API" na categoria Administração no menu à esquerda e clique em "Adicionar permissões" no meio.

Na solicitação de permissão da API, clique em Microsoft Graph.

Clique em Permitir aplicativo. Essa opção não está disponível para contas pessoais da Microsoft.

Uma lista de permissões será exibida abaixo, portanto, use o campo de pesquisa para verificar os itens a seguir.

  • Arquivos.ReadWrite.All

Isso é suficiente se você quiser usar apenas o OneDrive, mas se quiser acessar qualquer outra coisa, adicione permissões. As permissões necessárias para acessar o OneDrive podem ser encontradas na página oficial abaixo.

Depois de fazer suas seleções, clique no botão Adicionar permissões.

O adicionado é adicionado à lista e o "Tipo" é "Aplicativo". No entanto, como o "Status" é "Não concedido a XXXX", clique em "Dar consentimento do administrador a XXXX". (XXXX é o nome da sua organização)

Clique em Sim.

Ele muda para o estado concedido.

A propósito, você pode excluir o "User.Read delegado" que está lá desde o início, porque não o usaremos desta vez. Se você adicionou "User.Read" como um aplicativo, use-o.

Verificando IDs de usuário

Como você acessará o OneDrive que o usuário de destino possui, verifique o ID do usuário com antecedência.

Microsoft Entra ID e abra-o.

Selecione Usuários no menu à esquerda.

Uma lista de usuários será exibida, então clique no usuário de destino.

Anote o "ID do objeto", pois será o ID do usuário.

Criar um aplicativo de console

Inicie o Visual Studio e crie um projeto para seu aplicativo de console. Você pode criá-lo fora do Visual Studio, mas usarei o Visual Studio por enquanto.

O local e o nome do projeto são opcionais. Nesse caso, o nome do projeto é OneDriveApiDotNetClientCredentialsHttpClient .

Desta vez, não dividiremos o código, mas Program.cs o escreveremos escalonado a partir do topo, portanto, se você puder verificar o movimento, reescreva-o dividindo o código conforme necessário.

using System.Runtime.Serialization.Json;
using System.Text;
using System.Text.Json;
using System.Web;
using System.Xml;

Descreva o namespace que você deseja usar.

// 認証結果を格納するクラスです
public record TokenResponse(string token_type, int expires_in, int ext_expires_in, string access_token);

Essa classe é usada para receber informações de token após a autenticação. Program.cs , escreva-o no final do código. Você pode separar essa classe em outros arquivos.

// JSON 文字列を整形するメソッド
static string ConvertToIndentedJson(string json)
{
  byte[] buffer = Encoding.UTF8.GetBytes(json);
  using MemoryStream stream = new();
  using XmlDictionaryWriter writer = JsonReaderWriterFactory.CreateJsonWriter(stream, Encoding.UTF8, true, true);
  using XmlDictionaryReader reader = JsonReaderWriterFactory.CreateJsonReader(buffer, XmlDictionaryReaderQuotas.Max);
  writer.WriteNode(reader, true);
  writer.Flush();
  return Encoding.UTF8.GetString(stream.ToArray());
}

Este é um método mágico que formata o texto JSON recebido da API com recuo. Por se tratar de um código retirado da Internet, não explicarei o conteúdo em detalhes.

// 各種 ID などの定義
var clientId = "XXXXXXXX";      // クライアント ID
var tenantId = "XXXXXXXX";      // テナント ID
var clientSecret = "XXXXXXXX";  // クライアント シークレット
var userId = "XXXXXXXX";        // ユーザー ID
var accessToken = "";           // アクセストークン

Defina a ID obtida no Azure para cada um. accessToken é um token temporário para acessar o OneDrive, portanto, ele é definido em runtime.

// 各種 URL の定義
var urlToken = $"https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token";
var urlOneDriveGetRootFolders = $"https://graph.microsoft.com/v1.0/users/{userId}/drive/root/children";

O URL da API para autenticação e o URL da API para obter a lista de pastas na raiz do OneDvie. Esta é uma descrição de como verificar o acesso à API do OneDrive, portanto, não descreverei o conteúdo da API do OneDrive. Se você tiver acesso à API do OneDrive, fazer upload e download é um aplicativo, então não acho que seja tão difícil.

// 使いまわすので最初に定義しておく
HttpClient httpClient = new();

Você gerou um para fazer uma solicitação para HttpClient o URL especificado.

// 「Name1=Value1&Name2=Value2...」形式のクエリパラメータ文字列を作成する
var valueDict = new Dictionary<string, string>
{
    { "client_id", clientId },
    { "scope", "https://graph.microsoft.com/.default" },
    { "client_secret", clientSecret },
    { "grant_type", "client_credentials" },
};
var valueQS = string.Join("&", valueDict.Select(x => string.Format("{0}={1}", x.Key, HttpUtility.UrlEncode(x.Value))));
Console.WriteLine($"valueQS={valueQS}");

Primeiro, você fará uma solicitação à API de autenticação com dados, portanto, prepare esses dados. O formato dos dados a serem enviados é uma string de parâmetro de consulta no formato "Name1=Value1&Name2=Value2...", portanto, ele é criado em um dicionário e depois convertido em uma string de parâmetro de consulta.

Existem quatro parâmetros a serem enviados:

Exemplo de
valores de nome de parâmetro
client_id Defina a ID do cliente que você obteve no registro do aplicativo.
âmbito A autenticação com um segredo do cliente foi corrigida https://graph.microsoft.com/.default .
client_secret Defina o valor do segredo do cliente que você obteve no registro do aplicativo.
grant_type Como é autenticação com um segredo do cliente, client_credentials será

Para obter mais informações, consulte o seguinte site oficial.

// 認証処理
using (HttpRequestMessage request = new(HttpMethod.Post, urlToken))
{
  request.Content = new StringContent(valueQS, Encoding.UTF8, "application/x-www-form-urlencoded");

  // データを送信し結果を受け取る
  using var response = httpClient.SendAsync(request).Result;

  Console.WriteLine($"IsSuccessStatusCode={response.IsSuccessStatusCode}");
  Console.WriteLine($"StatusCode={response.StatusCode}");
  Console.WriteLine($"ReasonPhrase={response.ReasonPhrase}");

  if (response.IsSuccessStatusCode == false)
  {
    Console.WriteLine("トークンの取得に失敗しました。");
    return;
  }

  // レスポンスからアクセストークンを受け取る。
  var tokenResultJson = response.Content.ReadAsStringAsync().Result;
  Console.WriteLine($"tokenResultJson={ConvertToIndentedJson(tokenResultJson)}");

  var tokenResult = JsonSerializer.Deserialize<TokenResponse>(tokenResultJson) ?? throw new Exception("JSON をデシリアライズできませんでした。");
  accessToken = tokenResult.access_token;
}

HttpClient para fazer uma solicitação à API de autenticação. HttpClient É um uso comum, então não acho que haja muito o que prestar atenção.

Os dados a serem enviados devem ser codificados em UTF8 e o Content-Type deve ser application/x-www-form-urlencoded . O método é POST .

Se a resposta for verificada e processada IsSuccessStatusCode com êxito, você receberá o resultado como uma string JSON. O JSON que você recebe tem os seguintes parâmetros:

{
  "token_type": "Bearer",
  "expires_in": 3599,
  "ext_expires_in": 3599,
  "access_token": "XXXXXXXXXXXXXXX"
}

Neste, access_token usaremos . Use esse valor com a API do OneDrive. Você pode ignorar os outros parâmetros, masaccess_token se quiser saber a data de expiração do , use expires_in .

É difícil usá-lo como uma string JSON, então JsonSerializer.Deserialize nós o desserializamos com e, em seguida, access_token obtemos .

// OneDrive 処理
using (HttpRequestMessage request = new(HttpMethod.Get, urlOneDriveGetRootFolders))
{
  // アクセストークンをヘッダーに追加する
  request.Headers.Add("Authorization", "Bearer " + accessToken);

  // OneDrive API にリクエスト
  using var response = httpClient.SendAsync(request).Result;

  Console.WriteLine($"IsSuccessStatusCode={response.IsSuccessStatusCode}");
  Console.WriteLine($"StatusCode={response.StatusCode}");
  Console.WriteLine($"ReasonPhrase={response.ReasonPhrase}");

  if (response.IsSuccessStatusCode == false)
  {
    Console.WriteLine("OneDrive へのアクセスに失敗しました。");
    return;
  }

  // レスポンスからアクセストークンを受け取る。
  var apiResultJson = response.Content.ReadAsStringAsync().Result;
  Console.WriteLine($"apiResultJson={ConvertToIndentedJson(apiResultJson)}");
}

Por fim, use o token de acesso para fazer uma solicitação à API do OneDrive. O método especifica GET , mas depende do tipo de API, portanto, verifique a documentação da API do OneDrive.

Adicione o token de acesso ao cabeçalho. Defina a chave como Authorization e o valor no Bearer {アクセストークン} formato .

Tudo o que você precisa fazer é fazer uma solicitação e receber o resultado como uma string JSON. Agora que estamos apenas nos certificando de que temos acesso à API do OneDrive, estamos apenas formatando a cadeia de caracteres JSON e imprimindo-a no console. Na verdade, ele desserializa o JSON recebido e o processa de acordo.

Recebi uma lista de pastas desta vez, mas acho que o JSON é o seguinte.

{
  "@odata.context": "https:\/\/graph.microsoft.com\/v1.0\/$metadata#Collection(driveItem)",
  "value": [
    {
      "@microsoft.graph.Decorator": "decorator has been deprecated. Refer to folder.decorator",
      "createdBy": {
        "フォルダ作成者の情報":""
      },
      "createdDateTime": "2017-06-20T04:31:24Z",
      "eTag": "\"{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX},1\"",
      "id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
      "lastModifiedBy": {
        "フォルダ更新者の情報":""
      },
      "lastModifiedDateTime": "2017-06-20T04:31:24Z",
      "name": "フォルダ名",
      "parentReference": {
        "親フォルダの情報":""
      },
      "webUrl": "フォルダにアクセスできる URL",
      "cTag": "\"c:{5926E2DA-B7FF-4936-88A8-7908C378ECE2},0\"",
      "fileSystemInfo": {
        "createdDateTime": "2017-06-20T04:31:24Z",
        "lastModifiedDateTime": "2017-06-20T04:31:24Z"
      },
      "folder": {
        "childCount": 0
      },
      "size": 0,
      "specialFolder": {
        "name": "フォルダ名"
      }
    },
    :
  ]
}

Eu não acho que você precisa de todas as informações, então se você quiser obter apenas o nome da pasta, por exemplo, você value pode obter apenas os parâmetros da name matriz em .

Resumo

Se funcionar bem até agora, você poderá acessar o OneDrive com um programa em lote. Não sei se as dicas resumem os métodos de upload e download, mas basicamente deve funcionar se você aplicar a lista de pastas na raiz descrita acima. Os tipos de APIs estão resumidos no site oficial abaixo, portanto, encontre a API que deseja usar e implemente-a.

Obrigado

Eu tinha algumas perguntas sobre como usar a API do OneDrive desta vez, então fiz uma pergunta.