List Sheets with Google+ API for Domains not executing in access_denied

This is killing me! I am trying to list a user's Google Plus circles on my domain using domain delegation. This should be exactly what the google developer api example does.

I installed the app in Google Cloud console, enabled the Google+ Domains API and generated a server certificate.

Then I added a scope to the Google Apps Admin Console.

My code:

package com.MYDOMAIN.plus;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.List;

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.api.services.plusDomains.PlusDomains;
import com.google.api.services.plusDomains.model.Circle;
import com.google.api.services.plusDomains.model.CircleFeed;

public class PlusHelper {

    // Fill in the following values based upon the previous steps
    private static final String SERVICE_ACCOUNT_EMAIL = "39578475189-vefb22ohjt9dahloahfsp9h9bol7r6ie@developer.gserviceaccount.com";
    private static final String SERVICE_ACCOUNT_PKCS12_FILE_PATH =
        "/Users/kees/Documents/workspace/MYDOMAINPlus/2a282bbacf8895b821e7cf662a98de4d65e38b2a-privatekey.p12";
    private static final String USER_EMAIL = "kees@MYDOMAIN.com";

    // List the scopes your app requires. These must match the scopes
    // registered in the Admin console for your Google Apps domain.
    private static final List<String> SCOPE = Arrays.asList(
                "https://www.googleapis.com/auth/plus.circles.read");

    private static PlusDomains authenticate(final String userEmail) throws GeneralSecurityException, IOException {
      System.out.println(String.format("Authenticate the domain for %s", userEmail));

      HttpTransport httpTransport = new NetHttpTransport();
      JsonFactory jsonFactory = new JacksonFactory();

      // Setting the sub field with USER_EMAIL allows you to make API calls using the special keyword
      // "me" in place of a user id for that user.
      GoogleCredential credential = new GoogleCredential.Builder()
          .setTransport(httpTransport)
          .setJsonFactory(jsonFactory)
          .setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
          .setServiceAccountScopes(SCOPE)
          .setServiceAccountUser(USER_EMAIL)
          .setServiceAccountPrivateKeyFromP12File(
              new java.io.File(SERVICE_ACCOUNT_PKCS12_FILE_PATH))
          .build();

      // Create and return the authorized API client
      PlusDomains service = new PlusDomains.Builder(httpTransport, jsonFactory, credential).setApplicationName("PlusSync").build();
      return service;
    }

    public static void main(String[] args) {
            /** Global Drive API client. */
            PlusDomains plusDomains;
            try {
                plusDomains = PlusHelper.authenticate(USER_EMAIL);
                PlusDomains.Circles.List listCircles = plusDomains.circles().list(USER_EMAIL);
                listCircles.setMaxResults(5L);
                CircleFeed circleFeed = listCircles.execute();
                List<Circle> circles = circleFeed.getItems();

                // Loop until no additional pages of results are available.
                while (circles != null) {
                  for (Circle circle : circles) {
                    System.out.println(circle.getDisplayName());
                  }

                  // When the next page token is null, there are no additional pages of
                  // results. If this is the case, break.
                  if (circleFeed.getNextPageToken() != null) {
                    // Prepare the next page of results
                    listCircles.setPageToken(circleFeed.getNextPageToken());

                    // Execute and process the next page request
                    circleFeed = listCircles.execute();
                    circles = circleFeed.getItems();
                  } else {
                    circles = null;
                  }
                }
            } catch (GeneralSecurityException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }



    }
}

      

This results in an error:

com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request
{
  "error" : "access_denied"
}
    at com.google.api.client.auth.oauth2.TokenResponseException.from(TokenResponseException.java:105)
    at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:332)
    at com.google.api.client.auth.oauth2.TokenRequest.execute(TokenRequest.java:352)
    at com.google.api.client.googleapis.auth.oauth2.GoogleCredential.executeRefreshToken(GoogleCredential.java:269)
    at com.google.api.client.auth.oauth2.Credential.refreshToken(Credential.java:454)
    at com.google.api.client.auth.oauth2.Credential.intercept(Credential.java:215)
    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:854)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:410)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:460)
    at com.MYDOMAIN.plus.PlusHelper.main(PlusHelper.java:60)

      

Does anyone have an idea? This is killing me because I was working on a different domain before!

BTW, "MYDOMAIN" in all my code and stacktrace is a replacement for the actual domain, obviously.

0


source to share


1 answer


Found the answer after messing too much. It looks like in the new Cloud Console, the client ID for the certificate is different from the client ID in the OAuth field. What I did for this: upload the JSON of the certificate. This json contains a client_id value other than the client ID in the cloud console. Use client id from JSON in API admin panel to allow scopes and work!



+1


source







All Articles