16

簡単な質問は、これが可能かどうか、可能であればどのように行うかです。

概要

現在、サービス アカウントを使用して、Google Drive API を使用して Google Apps ドメイン全体の情報にアクセスする .NET アプリケーションを使用しています。これは、google-api-dotnet-client ライブラリとコードを使用して、こちらのサンプルに示されているのと同じ行に沿って正常に機能します。これは、現在、私が行っていることの非常に優れた基本的な例です。

私が今やりたいことは、それを拡張して、「新しい」google-api-dotnet-client ライブラリによって提供される API を使用するだけでなく、古いgoogle-gdata ライブラリを介して提供される古い「GData」ライブラリを使用することです。 、具体的には Spreadsheets API (そしておそらくもっと増えるでしょう)。

問題

ここで困難が生じます。前のライブラリは、上記の最初の段落の 2 番目のリンクで証明されているように、まさに私が望んでいることを実行します。ただし... 2 番目のライブラリは、OAuth 1.0 やその他の古い認証手法に加えて OAuth 2.0 をサポートするように更新されていますが、広範なグーグルと試行錯誤からわかる限り、"すべてのユーザーに代わってサービス アカウント」という操作が必要です。

私の質問は、私がやりたいことを実行できる何か (おそらく見つけにくいものや文書化されていないもの) が欠けているかどうかです。それができない場合、この動作を強制して、これら 2 つのライブラリを並べて動作させる方法はありますか?

理想的なソリューション

Google.GData.Spreadsheets.SpreadsheetsService理想的には、インスタンスが既に使用しているインスタンスを利用できるようにする何らかの方法が大好きGoogle.Apis.Authentication.Auth2Authenticator<AssertionFlowClient>です...どういうわけか。そのような魔術は可能ですか?私は明らかなことを見逃していますか?

それができない場合は、古いライブラリが処理できる何らかの方法で、必要に応じて OAuth2 の「アサーション フロー クライアント」ダンス全体をやり直します。

ヘルプ?

他の考え

私は、これを実現するためにゼロから始めて独自のライブラリを作成するというオプションを検討し、当分の間拒否しました。これには 2 つの理由があります。

  1. gdata ライブラリはすでに存在しており、おそらく私より賢い多くの人々によって開発されています。私は自分がもっとうまくやれると信じているほど傲慢ではありません。
  2. サービス アカウントを使用した OAuth2 アプローチが、これらの古い API でサポート/許可されているかどうかはわかりません。

私が避けたいと思っていたが、ここでの回答に応じてフォールバックする必要があるかもしれない別のアプローチは、これの一部に 2-legged OAuth 1.0 を使用することです。アプリの一部が 1 つの古い認証方法に依存しているのに対し、他の部分はそれを素晴らしい新しい方法で行っているため、私には間違っているように感じます。そして、もっとうまくいかないことがたくさんあります...


アップデート

GDataRequestFactory と GDataRequest をサブクラス化する可能性を検討したので、独自のリクエスト ファクトリを作成し、それが呼び出される直前にリクエストを認証するために介入できる のインスタンスGoogle.Apis.Authentication.Auth2Authenticator<AssertionFlowClient>(とにかく のインスタンス) を取得できるようにします。Google.Apis.Authentication.IAuthenticatorしかし... GDataRequest のコンストラクターは内部的なもので、私を止めました。

これは本当に意図されていないように見えます。

4

3 に答える 3

20

この質問に出くわした他の人々のために(受け入れられた回答にリンクされているソリューションは非推奨のコードを使用しているため)、ここで私がそれをどのように解決したかを示します。

まず、次の Google のサービス アカウントの例Google.Apis.Authを設定して、「新しい API」ランド (ナゲット パッケージを使用)から始めます。ServiceAccountCredential

//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));

認証情報にアクセス トークンを要求するように指示します。

credential.RequestAccessTokenAsync(System.Threading.CancellationToken.None).Wait();

ここで、"古い API" ランドに切り替えます ( Google.GData.Spreadsheetsnuget パッケージを使用します)。(Google の例SpreadsheetsServiceと同様) を構築することから始めます。

SpreadsheetsService service = new SpreadsheetsService("MySpreadsheetIntegration-v1");

サービス アカウント認証を使用するには、 のインスタンスを作成しGDataRequestFactory、カスタムAuthorizationヘッダーを設定します。

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

最後に、SpreadsheetsServiceRequestFactoryプロパティをこの新しいファクトリに設定します。

service.RequestFactory = requestFactory;

そしてSpreadsheetsService、他の手法を使用して認証した場合と同じように、 を使用してください。(ヒント:serviceAccountEmailアドレスをシートに招待して、スプレッドシートをサービス アカウントと共有します)

于 2014-10-08T14:27:50.153 に答える
4

GDataRequestFactory をサブクラス化し、GDataRequest によって実装されるインターフェイスの独自の実装を作成することで、この問題を解決することができました。この実装は、リフレクションによってインスタンス化された GDataRequest のインスタンスをラップし、IAuthenticator (私の場合は Auth2Authenticator) のインスタンスを使用して認証を実行するために必要なコードを追加します。

私はそれについてブログ投稿を書き、Gist として例を追加しました。

これが役立つ場合は、自由に使用してください (BSD ライセンス)。

于 2012-12-09T13:28:39.560 に答える