1

私は Google Apps ドメインの管理者であり、ドメイン上のユーザーの連絡先にアクセスするプログラムを作成しようとしています (共有の連絡先ではなく、各ユーザーの個々の連絡先にアクセスしようとしていることに注意してください。共有連絡先 API は役に立ちません)。

当初、私は 3 脚認証 (Web ページを表示し、ユーザーが承認し、そのトークンを使用する) の「推奨」アプローチを使用していました。自分以外のユーザーを試してみると、403禁止エラーが発生することを除いて、それはうまくいきました. それで、この場合、非推奨ですが、2足の認証が必要だったことを読みました。

さて、私はこのコードを思いつきましたが、今では 401/無許可の資格情報を取得しています. 問題が私のコードにあるのか、それとも別の場所にあるのか (アプリケーションの登録方法など) はわかりませんが、役立つドキュメントを見つけるのに非常に苦労しています。

      public static Feed<Contact> MakeRequest(string userId, int numberToRetrieve = 9999)
        {
          var settings = new RequestSettings(Properties.Settings.Default.ApplicationName,
            Properties.Settings.Default.ApiKey, Properties.Settings.Default.ConsumerSecret,
            Properties.Settings.Default.GoogleUserName, Properties.Settings.Default.Domain);
          var cRequest = new ContactsRequest(settings);
          var query = new ContactsQuery(ContactsQuery.CreateContactsUri(userId));
          query.NumberToRetrieve = numberToRetrieve;
          return cRequest.Get(query);
        }
4

2 に答える 2

1

3 レグ OAuth では、ユーザーが OAuth ハンドシェイクを介して明確に認証する場合にのみ機能します。すべてのユーザーに代わって呼び出しを行う場合は、OAuth 2.0 のサービス アカウントを使用する必要があります。

ドライブ API コードのサンプルを確認してください。OAuth 2.0 とサービス アカウントを開始する方法についていくつかのアイデアが得られます。

https://developers.google.com/drive/service-accounts#use_service_accounts_as_application-owned_accounts

OAuth 1.0 を使用している場合は、特別なパラメーター xoauth_requestor_id を使用する必要があります。これについての詳細は次のとおりです。

https://developers.google.com/accounts/docs/OAuth#GoogleAppsOAuth

于 2013-11-01T20:51:31.740 に答える
0

わかりました、私はついにそれを理解しました。これはおそらく動作するはずの方法ではないように感じ、ServiceAccountCredential のソース コードを掘り下げる必要がありましたが、動作します。実際にはこれを少し分割していますが、ここでは明確にするために完全に示しています。

また、Google.Apis.Authentication から Google.Apis.Auth に切り替えました。

    public static Feed<Contact> MakeRequest(string userId, int numberToRetrieve = 9999)
    {
        var serviceCredential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(ServiceEmail)
        {
            Scopes = new[] { @"https://www.google.com/m8/feeds/" },
            User = userId,
        }.FromCertificate(Certificate));

        var reqAccessTokenInfo = serviceCredential.GetType()
          .GetMethod("RequestAccessToken", BindingFlags.Instance | BindingFlags.NonPublic);
        var task = (Task<bool>) reqAccessTokenInfo.Invoke(serviceCredential, parameters: new object[] {new CancellationToken()});
        task.Wait();

        var settings = new RequestSettings(Properties.Settings.Default.ApplicationName, serviceCredential.Token.AccessToken);
        var cRequest = new ContactsRequest(settings);
        var query = new ContactsQuery(ContactsQuery.CreateContactsUri(userId)) { NumberToRetrieve = numberToRetrieve };

        return cRequest.Get<Contact>(query);
    }
于 2013-11-12T22:03:58.270 に答える