secret playground google apis google-api oauth-2.0 gdata-api google-contacts service-accounts

google api - playground - Accediendo a Api de Contactos de Google a través de OAuth 2.0 y la clave privada, también conocida como Cuenta de Servicio



google oauth demo (3)

Actualmente estoy implementando el acceso a Contactos de Google a través de OAuth 2.0 y una llamada Cuenta de servicio. La cuenta de servicio se genera para un usuario común como "[email protected]".

El código para generar las credenciales de OAuth 2.0 es:

public static GoogleCredential getCredentials() throws GeneralSecurityException, IOException { GoogleCredential credential = new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT) .setJsonFactory(JSON_FACTORY) .setServiceAccountId(SingleUserCredentials.SERVICE_ACCOUNT_EMAIL) .setServiceAccountScopes("https://www.google.com/m8/feeds") .setServiceAccountPrivateKeyFromP12File(new File(SingleUserCredentials.SERVICE_ACCOUNT_PKCS12_FILE_PATH)) .build(); credential.refreshToken(); return credential; }

Estoy tratando de recuperar los contactos a través de:

ContactsService myService = new ContactsService( "myApp"); myService.setOAuth2Credentials(getCredentials()); URL feedUrl = new URL("https://www.google.com/m8/feeds/contacts/default/full"); Query myQuery = new Query(feedUrl); ContactFeed resultFeed = myService.query(myQuery, ContactFeed.class); // Print the results for (ContactEntry entry : resultFeed.getEntries()) { System.out.println(entry.getName().getFullName().getValue()); System.out.println("Updated on: " + entry.getUpdated().toStringRfc822()); }

El problema es que no recibo ningún contacto de mi cuenta. La alimentación siempre está vacía. No hay error Nada.

Al acceder a un dominio administrado de Google Apps con el mismo enfoque, funciona bien.

Me pregunto si la API de contactos admite OAuth 2.0 para cuentas ordinarias (aka @ gmail.com) cuando se utiliza un archivo de clave p12 y una cuenta de servicio.


Me encontré con el mismo problema yo mismo.

Intenté tanto la dirección de correo electrónico que recibí cuando configuré la clave como la dirección de correo electrónico de un administrador de dominio.

Cuando uso el correo electrónico desde la configuración de la clave, no recibo nada, sin advertencias, sin excepciones y sin datos.

Cuando uso la dirección de correo electrónico de un administrador de dominio, recibo una excepción:

com.google.api.client.auth.oauth2.TokenResponseException: 400 OK [java] { [java] "error" : "invalid_grant" [java] } [java] Feb 5, 2013 5:16:48 PM com.google.appengine.repackaged.org.apache.http.impl.client.DefaultRequestDirector handleResponse [java] WARNING: Authentication error: Unable to respond to any of these challenges: {} [java] Feb 5, 2013 5:16:48 PM com.google.apphosting.utils.jetty.JettyLogger warn [java] WARNING: / [java] java.lang.NullPointerException: No authentication header information

...

Entonces, calculé que la dirección de correo electrónico del administrador del dominio no era lo que necesitaba.

Luego, busqué en Google por un tiempo antes de encontrar esta página:

http://javadoc.google-api-java-client.googlecode.com/hg/1.13.2-beta/com/google/api/client/googleapis/auth/oauth2/GoogleCredential.html

Vi allí GetServiceAccountUser (). La descripción del campo fue:

Devuelve la dirección de correo electrónico del usuario que la aplicación intenta suplantar en el flujo de la cuenta de servicio o nulo para ninguno o si no utiliza el flujo de la cuenta de servicio.

Efectivamente, hay un setServiceAccountUser (String) correspondiente que acepta el nombre de usuario (dirección de correo electrónico) del usuario al que está usando la cuenta de servicio para suplantar.

Establecí ese campo en un valor apropiado y pude continuar.

En retrospectiva, todo tiene sentido: si no proporciono una cuenta de la que estoy tratando de trabajar, no puedo retirar los contactos para esa cuenta.


Actualmente no es posible acceder a Contactos usando una cuenta de servicio, ya que no es compatible con la Consola de API de Google en la Consola de API de Google .

Ver también: Cuentas de servicio

En segundo lugar, solo funcionaría con un dominio administrado de Google porque el administrador del dominio debe otorgar acceso a la cuenta del servicio a través del siguiente proceso:

Delegar la autoridad de todo el dominio a su cuenta de servicio

La cuenta de servicio que creó ahora debe tener acceso a los datos de usuario del dominio de Google Apps a los que desea acceder. Las siguientes tareas deben ser realizadas por un administrador del dominio de Google Apps:

  1. Vaya al panel de control de su dominio de Google Apps. La URL debe tener el siguiente aspecto: "www.google.com/a/cpanel/mydomain.com"

  2. Vaya a Herramientas avanzadas ...> Administre el acceso de terceros al Cliente OAuth.

  3. En el campo Nombre del cliente, ingrese la ID del cliente de la cuenta de servicio.

  4. En el campo One or More API Scopes, ingrese la lista de ámbitos a los que se debe otorgar acceso a su aplicación.

  5. Haga clic en el botón Autorizar.


Hoy me he encontrado con este mismo error, pero por el momento he renunciado al uso de las Cuentas de servicio, que supongo que actualmente no es compatible con la API de Contactos. Y entonces estoy usando Contacts API v3 con OAuth 1.0 y obtengo los resultados esperados.

ContactsService contactsService = new ContactsService(APPLICATION_NAME); contactsService.setUserCredentials(CLIENT_USERNAME, CLIENT_SECRET); URL contactFeedURL = new URL("https://www.google.com/m8/feeds/contacts/default/full"); Query contactFeedQuery = new Query(contactFeedURL); ContactFeed contactFeed = contactsService.getFeed(contactFeedQuery, ContactFeed.class);