質問

I am an administrator of a Google Apps domain and am trying to write a program that will access the contacts of users on the domain (note that I'm not trying to get at the shared contacts, but the individual contacts for each user, so the shared contacts API won't help).

Initially I was using the "recommended" approach of three-legged auth (show a Web page, the user approves, use that token). That worked great, except if I tried any user other than myself I'd get a 403 forbidden error. So then I read that in this case I wanted two-legged auth, although it's deprecated.

Well, I've come up with this code but now I'm getting a 401/unauthorized credential. I'm not sure if the problem lies in my code or somewhere else (the way I registered the application or something) but I'm having a really hard time finding helpful documentation.

      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);
        }
役に立ちましたか?

解決 2

OK, I finally figured it out. I feel like this probably isn't the way it's supposed to work and I had to dig around the source code of ServiceAccountCredential, but it works. I actually have this split out a bit, but for the sake of clarity here it is altogether.

I also switched from Google.Apis.Authentication to 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);
    }

他のヒント

With 3 legged OAuth, it only works if the user specifically authenticates via OAuth handshake. If you want to make call on behalf of all your users, you will need use service account for OAuth 2.0.

Check out the drive API code sample, it will give you some ideas how to start with OAuth 2.0 and service account.

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

If you are using OAuth 1.0, then you will need use the special parameter xoauth_requestor_id. Here is more information about it:

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top