Попытка выполнить простой тест API-интерфейса Google с использованием сетевой библиотеки Google и учетной записи службы.

Я собрал приведенный ниже пример кода, используя вспомогательный код, поставляемый с примерами Google для клиентских библиотек dotnet google API.

Проблема: в нем нет информации о каких-либо файлах, хотя я загрузил один файл в учетную запись Google, которой принадлежит эта учетная запись службы.

Когда я попытался использовать авторизацию oauth, чтобы сделать то же самое, я получил ожидаемый результат (я сделал это на этой странице: https://developers.google.com/drive/v2/reference/files/list).

Может быть, есть проблема с областью действия или что-то в этом роде; Любые идеи?

Мои попытки зарегистрировать все HTTP-запросы и ответы полностью провалились. Клиентские библиотеки Google, похоже, ведут журнал для каждого API, и я не вижу ничего для диска Google. Также использование log4net с dotnetopenauth ничего не дало, когда я пробовал (клиентские библиотеки Google используют открытую аутентификацию dot net).

Вот код:

using System;
using System.Security.Cryptography.X509Certificates;
using Google.Apis.Authentication.OAuth2;
using Google.Apis.Authentication.OAuth2.DotNetOpenAuth;
using Google.Apis.Drive.v2;
using Google.Apis.Util;
using Google.Apis.Services;

namespace Drive.ServiceAccount
{
    class Program
    {

        static Program()
        {
//
            //ApplicationContext.RegisterLogger(new Log4NetLogger());
            log4net.Config.XmlConfigurator.Configure();          
        }

        private const string SERVICE_ACCOUNT_EMAIL = "<blablalba>@developer.gserviceaccount.com";
        private const string SERVICE_ACCOUNT_PKCS12_FILE_PATH = @"<blablalba>-privatekey.p12";

        /// <summary>
        /// Build a Drive service object authorized with the service account.
        /// </summary>
        /// <returns>Drive service object.</returns>
        static DriveService BuildService()
        {
            X509Certificate2 certificate = new X509Certificate2(SERVICE_ACCOUNT_PKCS12_FILE_PATH, "notasecret",
                X509KeyStorageFlags.Exportable);

            var _client = new AssertionFlowClient(GoogleAuthenticationServer.Description, certificate)
            {
                ServiceAccountId = SERVICE_ACCOUNT_EMAIL,
                Scope = DriveService.Scopes.Drive.GetStringValue(),
            };
            var auth = new OAuth2Authenticator<AssertionFlowClient>(_client, AssertionFlowClient.GetState);

            var service = new DriveService(new BaseClientService.Initializer()
            {
                Authenticator = auth,
                ApplicationName = "Drive API Sample",
            });

            return service;
        }

        static void Main(string[] args)
        {
            var _driveService = BuildService();

            var _files = _driveService.Files.List().Execute();

            foreach (var _file in _files.Items)
            {
                Console.WriteLine(_file.Id);
            }

            Console.WriteLine("Done");

            Console.ReadLine();
        }

    }
}

Спасибо Robadob за исправление моего недопонимания относительно сервисных аккаунтов. Вот некоторый рабочий код (только основной метод со всем остальным, как указано выше):

static void Main(string[] args)
{

    String _newFileName = Guid.NewGuid().ToString() + ".xml";

    new XDocument( new XElement("root", new XElement("someNode", "someValue")))
        .Save(_newFileName);

    Console.WriteLine("New file saved locally with name {0}.", _newFileName);

    var _driveService = BuildService();

    // upload the file:

    //var uploadStream = 
    //    new System.IO.FileStream(_newFileName, System.IO.FileMode.Open, System.IO.FileAccess.Read);

    byte[] byteArray = System.IO.File.ReadAllBytes(_newFileName);
    MemoryStream _byteStream = new MemoryStream(byteArray);

    var insert = _driveService.Files.Insert(new Google.Apis.Drive.v2.Data.File
    {
        Title = _newFileName,
    }, _byteStream, "text/xml");

    Task _uploadTask = insert.UploadAsync();

    _uploadTask.ContinueWith(t => Console.WriteLine("Upload Task Completed"),TaskContinuationOptions.OnlyOnRanToCompletion);
    //

    try
    {
        _uploadTask.Wait();
    }
    catch (AggregateException _ex)
    {
        foreach (Exception ex in _ex.Flatten().InnerExceptions)
        {
            Console.WriteLine(ex.Message);
        }
    }

    Console.WriteLine("Reading files");

    var _files = _driveService.Files.List();


    foreach (var _file in _files.Execute().Items)
    {
        Console.WriteLine(_file.Id);
    }

    Console.WriteLine("Done");

    Console.ReadLine();
}

person Elliot    schedule 06.08.2013    source источник


Ответы (1)


Поскольку это служебная учетная запись, я не думаю, что у нее есть собственный «Google Диск», служебные учетные записи существуют для того, чтобы действовать от имени пользователя.

Чтобы «олицетворять» пользователя, файлы которого вы хотите перечислить, вам нужно передать параметр prn при создании токена доступа;

Подробности можно найти здесь, если вы прокрутите вниз до «Дополнительных требований»; https://developers.google.com/accounts/docs/OAuth2ServiceAccount#formingclaimset

Похоже, что вы можете установить пользователя через это;

        var _client = new AssertionFlowClient(GoogleAuthenticationServer.Description, certificate)
        {
            ServiceAccountId = SERVICE_ACCOUNT_EMAIL,
            Scope = DriveService.Scopes.Drive.GetStringValue(),
            ServiceAccountUser = "[email protected]"
        };

Если вы хотите регистрировать HTTP-взаимодействия, я обнаружил, что Fiddler настроить намного проще, чем другие методы.

person Robadob    schedule 06.08.2013
comment
Черт, я слышал о олицетворении, но я думал, что другая идея учетной записи службы заключается в том, что приложение может иметь свои собственные ресурсы и получать к ним доступ. - person Elliot; 06.08.2013
comment
Возможно, это возможно (я не использовал API-интерфейс Google Диска), однако в своем вопросе вы говорите, что добавили файл пользователю, которому принадлежит учетная запись службы (а не диск учетных записей службы). Я бы не ожидал, что вы сможете получить доступ к файлам учетных записей службы не через API, поэтому попробуйте добавить файл через учетную запись службы через API. - person Robadob; 06.08.2013
comment
Хорошо спасибо; теперь может быть ясно. Учетная запись службы отделена от учетной записи Google, в консоли которой я создал учетную запись службы. Спасибо вам за помощь. - person Elliot; 06.08.2013