使用OAuth 2和服务帐户访问旧的GData API(电子表格API)

Mar*_*ing 16 .net c# gdata-api oauth-2.0 google-spreadsheet-api

简短的问题是这是否可能,如果可能,如何?

大纲

我有一个.NET应用程序,它目前使用服务帐户使用Google Drive API访问Google Apps域中的信息.这可以正常使用google-api-dotnet-client库和代码沿着这里的示例所示的相同行- 这是目前我正在做的一个非常好的基本示例.

我现在要做的是扩展它以及使用 "新"google-api-dotnet-client库提供那些API,它使用旧的"GData"库,通过较旧的google-gdata库提供,特别是Spreadsheets API(也许还有更多).

问题

这就是出现困难的地方.前一个库完全符合我的要求,正如上面第一段中的第二个链接所证明的那样 - 以及我自己做它的事实.但是 ......虽然第二个库已经更新,除了OAuth 1.0和其他旧的auth技术之外还支持OAuth 2.0,但据我所知,从广泛的谷歌搜索和跟踪错误中可以看出,"代表我所有用户的服务帐户"我需要的操作.

我的问题是我是否遗漏了一些东西(可能很难找到或没有记载的东西),这些东西可以让我做我想做的事.如果不这样做,有什么方法可以强迫这种行为并使这两个库并排运行?

理想的解决方案

理想情况下,我希望某种方式让Google.GData.Spreadsheets.SpreadsheetsService实例能够利用Google.Apis.Authentication.Auth2Authenticator<AssertionFlowClient>我已经在使用的实例...不知何故.这种巫术有可能吗?我错过了那个显而易见的东西吗?

如果不这样做,我很高兴再次完成整个OAuth2"断言流客户端"的舞蹈,如果我不得不以某种方式让旧库可以处理.

救命?

其他想法

我考虑过 - 暂时拒绝 - 选择从头开始编写我自己的库来实现这一目标.这有两个原因:

  1. gdata库已经存在,并且已经被许多人开发,可能比我自己聪明.我不是那么傲慢,我相信我能做得更好.
  2. 我不确定这些旧API上是否支持/允许使用服务帐户方法的OAuth2.

我一直希望避免但可能不得不依赖于此处的答案的另一种方法是使用2脚OAuth 1.0来实现这一点.我宁愿不这样做,因为应用程序的某些部分依赖于一种旧的auth方法,而其他部分则使用这种新方式对我来说感觉不对.而且还有更多的问题......


更新

我已经考虑过继承GDataRequestFactory和GDataRequest的可能性,所以我可以创建自己的请求工厂,然后获取Google.Apis.Authentication.Auth2Authenticator<AssertionFlowClient>(好的,Google.Apis.Authentication.IAuthenticator无论如何的实例)的实例,它可以在调用之前调试请求.但是...... GDataRequest的构造函数是内部的,这已经阻止了我.

它真的看起来不是这个意思.

小智 20

为了遇到这个问题的其他人(现在在接受的答案中链接的解决方案使用了弃用的代码),这就是我解决它的方法:

首先,Google.Apis.Auth通过设置ServiceAccountCredential以下Google的服务帐户示例,在"新API"土地上开始(使用nuget包):

//In the old api, this accessed the main api accounts' sheets, not anymore
//** Important ** share spreadsheets with the Service Account by inviting the "serviceAccountEmail" address to the sheet
string serviceAccountEmail = "12345697-abcdefghijklmnop@developer.gserviceaccount.com";

var certificate = new X509Certificate2(@"key.p12", "notasecret", X509KeyStorageFlags.Exportable);

ServiceAccountCredential credential = new ServiceAccountCredential(
   new ServiceAccountCredential.Initializer(serviceAccountEmail)
   {
       Scopes = new[] { "https://spreadsheets.google.com/feeds", "https://docs.google.com/feeds" }
   }.FromCertificate(certificate));
Run Code Online (Sandbox Code Playgroud)

告知凭证请求访问令牌:

credential.RequestAccessTokenAsync(System.Threading.CancellationToken.None).Wait();
Run Code Online (Sandbox Code Playgroud)

现在是时候切换回"旧API"土地(使用Google.GData.Spreadsheetsnuget包).首先构建SpreadsheetsService(类似于Google的示例):

SpreadsheetsService service = new SpreadsheetsService("MySpreadsheetIntegration-v1");
Run Code Online (Sandbox Code Playgroud)

要使用服务帐户身份验证,我们将创建一个实例GDataRequestFactory并设置自定义Authorization标头:

var requestFactory = new GDataRequestFactory("My App User Agent");
requestFactory.CustomHeaders.Add(string.Format("Authorization: Bearer {0}", credential.Token.AccessToken));
Run Code Online (Sandbox Code Playgroud)

最后,将SpreadsheetsService's RequestFactory属性设置为这个新工厂:

service.RequestFactory = requestFactory;
Run Code Online (Sandbox Code Playgroud)

然后继续使用SpreadsheetsService您使用任何其他技术进行身份验证的方式.(提示:通过邀请表格的serviceAccountEmail地址与服务帐户共享电子表格)