1

我是 Google Apps 域的管理员,我正在尝试编写一个程序来访问域中用户的联系人(请注意,我不是试图获取共享联系人,而是每个用户的个人联系人,所以共享联系人 API 无济于事)。

最初,我使用的是三足身份验证的“推荐”方法(显示网页,用户批准,使用该令牌)。效果很好,除非我尝试除我自己以外的任何用户,否则我会收到 403 禁止错误。所以然后我读到在这种情况下我想要两条腿的身份验证,尽管它已被弃用。

好吧,我想出了这段代码,但现在我得到了 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 回答