C# 使用OAuth 2和服务帐户访问较旧的GDataAPI(电子表格API)
简短的问题是,这是否可能,如果可能,如何实现 轮廓 我有一个.NET应用程序,它目前使用一个服务帐户使用Google Drive API访问Google应用程序域中的信息。这可以很好地使用和代码,这是目前我正在做的一个非常好的基本示例 我现在想做的是扩展它,通过“新的”google api dotnet客户端库,它使用旧的“GData”库,正如通过 更老的,特别是电子表格API(可能还有更多) 问题 这就是困难所在。前一个图书馆做的正是我想要的,正如上面第一段中的第二个链接所证明的那样——事实上我自己也在做然而。。。尽管第二个库已经更新,除了OAuth 1.0和其他较旧的身份验证技术外,还支持OAuth 2.0,但它不允许我需要的“代表所有用户的服务帐户”操作(从大量的谷歌搜索和跟踪错误中可以看出) 我的问题是,我是否遗漏了一些可以让我做我想做的事情的东西(可能是很难找到或没有记录的东西)。如果做不到这一点,我有没有办法强迫这种行为,让这两个库同时运行 理想溶液 理想情况下,我希望通过某种方式让C# 使用OAuth 2和服务帐户访问较旧的GDataAPI(电子表格API),c#,.net,oauth-2.0,gdata-api,google-spreadsheet-api,C#,.net,Oauth 2.0,Gdata Api,Google Spreadsheet Api,简短的问题是,这是否可能,如果可能,如何实现 轮廓 我有一个.NET应用程序,它目前使用一个服务帐户使用Google Drive API访问Google应用程序域中的信息。这可以很好地使用和代码,这是目前我正在做的一个非常好的基本示例 我现在想做的是扩展它,通过“新的”google api dotnet客户端库,它使用旧的“GData”库,正如通过 更老的,特别是电子表格API(可能还有更多) 问题 这就是困难所在。前一个图书馆做的正是我想要的,正如上面第一段中的第二个链接所证明的那样——事实上
Google.GData.Spreadsheets.Spreadsheets服务
实例能够利用我正在使用的Google.api.Authentication.Auth2Authenticator
实例。。。以某种方式这样的巫术可能吗?我错过了显而易见的事情
如果做不到这一点,我很乐意在必要时再次跳整个OAuth2“断言流客户机”舞,以旧库可以处理的方式
帮忙
其他想法
我已经考虑过——并且暂时拒绝——从零开始,编写自己的库来实现这一目标。这有两个原因:
更新 我已经考虑了将GDataRequestFactory和GDataRequest子类化的可能性,这样我就可以创建自己的请求工厂,并以
Google.api.Authentication.Auth2Authenticator
为例(当然,还是Google.api.Authentication.iaauthenticator
的一个实例)它可以在调用请求之前对请求进行身份验证。然而。。。GDataRequest的构造函数是内部的,这已经阻止了我
看起来这并不是我的本意。我通过子类化GDataRequestFactory并创建我自己的由GDataRequest实现的接口实现来解决这个问题。此实现封装了通过反射实例化的GDataRequest实例,并添加了使用IAAuthenticator实例(在我的示例中为Auth2Authenticator)执行身份验证所需的代码 我写了一篇关于它的博客文章,并添加了一个示例作为要点:
如果这对您有帮助,请随意使用(BSD许可证)。为了让其他人遇到这个问题(现在,在接受的答案中链接的解决方案使用了不推荐的代码),以下是我解决这个问题的方法: 首先,从“新API”开始(使用
Google.API.Auth
nuget包),通过设置一个ServiceAccountCredential
以下Google的:
//在旧的api中,它访问了主要api帐户的工作表,不再访问了
//**重要信息**通过邀请“serviceAccountEmail”地址与服务帐户共享电子表格
字符串serviceAccountEmail=“12345697-abcdefghijklmnop@developer.gserviceaccount.com";
var证书=新的X509Certificate2(@“key.p12”,“notasecret”,X509keystrageFlags.Exportable);
ServiceAccountCredential credential=新ServiceAccountCredential(
新ServiceAccountCredential.初始值设定项(serviceAccountEmail)
{
作用域=新[]{”https://spreadsheets.google.com/feeds", "https://docs.google.com/feeds" }
}.FromCertificate(证书));
告诉凭证请求访问令牌:
credential.RequestAccessTokenAsync(System.Threading.CancellationToken.None).Wait();
现在是时候切换回“旧API”领域了(使用Google.GData.Spreadsheets
nuget包)。首先构建电子表格服务
(与谷歌类似):
spreadsheets服务=新的电子表格服务(“MySpreadsheetIntegration-v1”);
要使用服务帐户身份验证,我们将创建GDataRequestFactory
的一个实例,并设置一个自定义Authorization
头:
var requestFactory=new-GDataRequestFactory(“我的应用程序用户代理”);
Add(string.Format(“Authorization:Bearer{0}”,credential.Token.AccessToken));
最后,将电子表格服务
的请求工厂
属性设置为此新工厂:
service.RequestFactory=RequestFactory;
然后继续使用电子表格服务
,就像使用任何其他技术进行身份验证一样。(提示:通过邀请服务帐户em与服务帐户共享电子表格
public class OAuthTest
{
OAuth2Parameters param = new OAuth2Parameters();
public OAuthTest()
{
Debug.WriteLine("Calling: AuthGoogleDataInterface()");
bool init = AuthGoogleDataInterface();
if (init)
{
GOAuth2RequestFactory requestFactory = new GOAuth2RequestFactory(null, "My App User Agent", this.param);
//requestFactory.CustomHeaders.Add(string.Format("Authorization: Bearer {0}", credential.Token.AccessToken));
var service = new SpreadsheetsService("MyService");
service.RequestFactory = requestFactory;
SpreadsheetQuery query = new SpreadsheetQuery();
// Make a request to the API and get all spreadsheets.
SpreadsheetFeed feed = service.Query(query);
// Iterate through all of the spreadsheets returned
foreach (SpreadsheetEntry entry in feed.Entries)
{
// Print the title of this spreadsheet to the screen
Debug.WriteLine(entry.Title.Text);
}
}
Debug.WriteLine(m_Init);
}
private bool AuthGoogleDataInterface()
{
bool b_success;
try
{
Console.WriteLine("New User Credential");
// New User Credential
UserCredential credential;
using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
{
GoogleClientSecrets GCSecrets = GoogleClientSecrets.Load(stream);
string[] ArrScope = new[] { "https://spreadsheets.google.com/feeds", "https://docs.google.com/feeds" };
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GCSecrets.Secrets,
ArrScope,
"user", CancellationToken.None,
new FileDataStore("My.cal")).Result;
// put the Information generated for the credentials object into the OAuth2Parameters-Object to access the Spreadsheets
this.param.ClientId = GCSecrets.Secrets.ClientId; //CLIENT_ID;
this.param.ClientSecret = GCSecrets.Secrets.ClientSecret; //CLIENT_SECRET;
this.param.RedirectUri = "urn:ietf:wg:oauth:2.0:oob"; //REDIRECT_URI;
this.param.Scope = ArrScope.ToString();
this.param.AccessToken = credential.Token.AccessToken;
this.param.RefreshToken = credential.Token.RefreshToken;
}
Debug.WriteLine("AuthGoogleDataInterface: Success");
b_success = true;
}
catch (Exception e)
{
Debug.WriteLine(e.ToString());
b_success = false;
}
return b_success;
}
}