我将下面的示例代码放在一起,使用谷歌的dot net google api客户端库的示例附带的一些帮助代码。
问题:即使我将一个文件信息上传到拥有此服务帐户的Gooogle帐户,它也不会列出任何文件信息。
当我尝试使用oauth授权执行同样的操作时,我得到了预期的结果(我在此页面上执行了此操作:https://developers.google.com/drive/v2/reference/files/list)。
可能存在范围问题或其他问题;有任何想法吗?
我尝试记录所有http请求和响应已完全失败。谷歌客户端库似乎已经基于per-api登录,我看不到任何谷歌驱动器。当我尝试使用log4net和dotnetopenauth时也没有做任何事情(google的客户端库使用dot net open auth)。
以下是代码:
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();
}
答案 0 :(得分:0)
由于它是一个服务帐户我不相信它有自己的“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 = "Name@Company.com"
};
如果您希望记录HTTP交互,我发现Fiddler比其他方法更容易设置。