Я пытался следовать простому примеру, указанному здесь: https://developers.google.com/admin-sdk/directory/v1/quickstart/dotnet
Разница в том, что я сгенерировал учетную запись учетной записи службы и назначил ее в качестве делегата с владельцем роли, поэтому он имеет полный доступ. Я также назначил ему правильные пространства имен для областей.
Здесь он имеет доступ к органам , что я пытаюсь перечислить в Справочнике API
Здесь определена моя учетная запись службы
Вот мои учетные данные
Я скачал JSON для учетных данных и добавил его в свой проект. Я могу подтвердить, что код загружает ServiceAccountCredential, успешно аутентифицируется и получает токен доступа путем проверки отладчика.
Но затем я передаю учетные данные инициализатору службы, и когда я создаю и выполняю запрос, он не работает с
{"Google.Apis.Requests.RequestError\r\nLogin Required [401]\r\nErrors [\r\n\tMessage[Login Required] Location[Authorization - header] Reason[required] Domain[global]\r\n]\r\n"}
Вот код:
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using System;
using System.Collections.Generic;
using System.IO;
namespace DirectoryQuickstart
{
class Program
{
static string[] Scopes = { DirectoryService.Scope.AdminDirectoryUser, DirectoryService.Scope.AdminDirectoryOrgunit };
static string ApplicationName = "slea-crm";
static string Secret = "gsuite-secret.json";
static void Main(string[] args)
{
ServiceAccountCredential sac = GoogleCredential.FromFile(Secret).CreateScoped(Scopes).UnderlyingCredential as ServiceAccountCredential;
var token = sac.GetAccessTokenForRequestAsync().Result;
// Create Directory API service.
var service = new DirectoryService(new BaseClientService.Initializer()
{
HttpClientInitializer = sac,
ApplicationName = ApplicationName,
});
OrgunitsResource.ListRequest request = service.Orgunits.List(customerId: "REDACTED");
IList<OrgUnit> orgUnits = request.Execute().OrganizationUnits;
if (orgUnits != null && orgUnits.Count > 0)
{
foreach (var orgUnit in orgUnits)
{
Console.WriteLine("{0} ({1})", orgUnit.Name, orgUnit.OrgUnitPath);
}
}
else
{
Console.WriteLine("No orgunits found.");
}
Console.Read();
}
}
}
Вот содержимое моего секрета JSON (с редакциями)
Что мне здесь не хватает?
РЕДАКТИРОВАТЬ : ОК, я делаю код останова, пока он генерирует запрос, и я вижу, что нигде не указано, как он устанавливает носитель токена авторизации в заголовках. Зачем? Я ожидаю, что этот класс HttpClientInitializer позаботится об этом, поскольку в документации API говорится, что он знает, как с этим справиться, и каждый найденный в Интернете пример показывает, что он просто передает учетные данные в инициализатор службы. Но когда я прошел через это, хотя учетным данным уже был предоставлен токен доступа, и он существует внутри него, нигде в запросе не обновляется заголовок.
Единственное, что я могу видеть, - это какой-то способ добавить перехватчик HTTP-запросов, где, возможно, я мог бы сделать это сам, но вау, это кажется действительно ... странным - после всей этой работы, которую они проделали на клиенте dotnet SDK, я, честно говоря, мог бы просто написать прямо в HTTP API, и было бы намного проще и легче следовать.