2

I'm trying to get the "Google Domain Shared Contacts API" described here: https://developers.google.com/admin-sdk/domain-shared-contacts/

Working using "OAuth 2.0 for Server to Server Applications" described here: https://developers.google.com/accounts/docs/OAuth2ServiceAccount

The recommendation from the OAuth page is to use the provided Google client library... I'm using the Java library. But the Shared-Contacts API doesn't have an example that uses this library, and I'm having trouble figuring out how to use the library with the Shared-Contacts API.

I am able to make the example for the OAuth to work for me... It uses Google Cloud Storage. Here's a snippet of the code:

String STORAGE_SCOPE = "https://www.googleapis.com/auth/devstorage.read_write";
try {
          try {
      httpTransport = GoogleNetHttpTransport.newTrustedTransport();
      String p12Content = Files.readFirstLine(new File(keyFile), Charset.defaultCharset());
      // Build service account credential.
      GoogleCredential credential = new GoogleCredential.Builder().setTransport(httpTransport)
          .setJsonFactory(JSON_FACTORY)
          .setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
          .setServiceAccountScopes(Collections.singleton(STORAGE_SCOPE))
          .setServiceAccountPrivateKeyFromP12File(new File(keyFile))
          .build();

      // Set up and execute Google Cloud Storage request.
      String URI;

      URI = "https://storage.googleapis.com/" + BUCKET_NAME;
      HttpRequestFactory requestFactory = httpTransport.createRequestFactory(credential);
      GenericUrl url = new GenericUrl(URI);
      HttpRequest request = requestFactory.buildGetRequest(url);
      HttpResponse response = request.execute();
      content = response.parseAsString();
          } catch (IOException e) {
              System.err.println(e.getMessage());
            }
          } catch (Throwable t) {
            t.printStackTrace();
          }   
      return content;

It's a request to get a listing of what's in a certain bucket on GCS. It calls a specific URL using the Credentials object, where the Credentials object does the work of the OAuth, using a key file I downloaded. There's other steps involved for getting it to work (setting the service account email, etc), which I did. It returns an xml string containing what is inside the bucket, and it works fine for me.

I then tried changing the URI to this string: URI = "https://www.google.com/m8/feeds/contacts/myGoogleAppsDomain.com/full"; and I changed the STORAGE_SCOPE variable to be this string: STORAGE_SCOPE = "http://www.google.com/m8/feeds/";

Hoping it would then return an xml-string of the shared-contacts. But instead, it returns this error: 403 Cannot request contacts belonging to another domain

I believe I'm getting this error because I'm not specifying the "hd" parameter when I do the authentication request... However, I'm unsure how I can specify the "hd" parameter using the GoogleCredential object (or the other parameters, except for "scope")... Can someone help me with that?

user542103
  • 255
  • 3
  • 18

1 Answers1

3

I think the issue here is that you are not specifying which user you want to impersonate in the domain (and you haven't configured the security settings in your domain to authorize the service account to impersonate users in the domain).

The doubleclick API auth documentation has good examples on how to do this. You can use their sample and replace the scopes and API endpoint:

https://developers.google.com/doubleclick-publishers/docs/service_accounts#benefits

breno
  • 3,226
  • 1
  • 22
  • 13
  • So are you saying that the Google Shared Contacts API requires the impersonation of one of the domain users? I was hoping that it was like the Cloud Storage API, and would not require it if it is done under the service account. – user542103 May 24 '14 at 16:39
  • The usual thing is to impersonate an admin user. I agree that for some APIs it's quite pointless to choose an account but that is the way you need to follow. – AMS May 26 '14 at 08:48