2012-08-06 31 views
5

Estoy intentando utilizar la API de Oauth para autenticar una cuenta de servicio de Google a través de la API de Java. Espero utilizarlo para acceder a Google Bigquery. Recibo una "subvención inválida" devuelta por mis solicitudes de API.Autenticar la API de Google con una cuenta de servicio con la API de Java

Aquí está el código, que es una copia de un ejemplo básico de autenticación (que no era para bigquery .. pero otra API de Google):

/** Global instance of the HTTP transport. */ 
    private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport(); 

    /** Global instance of the JSON factory. */ 
    private static final JsonFactory JSON_FACTORY = new JacksonFactory(); 

    private static Bigquery bigquery; 

public ServiceAccountExample() { 

     try { 
      try { 

      GoogleCredential credential = new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT) 
       .setJsonFactory(JSON_FACTORY) 
       .setServiceAccountId(SERVICE_ACCOUNT_EMAIL) 
       .setServiceAccountScopes(BigqueryScopes.BIGQUERY) 
       .setServiceAccountPrivateKeyFromP12File(new File("GoogleBigQuery-privatekey.p12")) 
       //.setRefreshListeners(refreshListeners) 
       //.setServiceAccountUser("email.com") 
       .build(); 


      credential.refreshToken(); 

      bigquery = new Bigquery.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential) 
         //.setApplicationName("GoogleBigQuery/1.0") 
         .build(); 

      listDatasets(bigquery, "publicdata"); 

      return; 
      } catch (IOException e) { 
      System.err.println(e.getMessage()); 
      } 
     } catch (Throwable t) { 
      t.printStackTrace(); 
     } 

} 

SERVICE_ACCOUNT_EMAIL es la dirección de correo electrónico de la forma: XXXXXXX @ developer.gserviceaccount.com

Si elimino la línea credential.refreshToken(), falla en los listsDatasets en la primera llamada a Bigquery ... De lo contrario, falla en credential.refreshToken() .. con el mismo error .

¿BigQuery no acepta la autenticación de cuenta de servicio?

Creo que he hecho todo correctamente a través de la consola API. Tengo:

  • Se ha activado el acceso a la API Big Query en.
  • Creó una cuenta de servicio en la pestaña "Acceso a la API".
  • Descargado mi clave privada (que se referencia desde el código anterior).
  • Dado que el usuario de mi cuenta de servicio "puede editar" el acceso en la pestaña "Equipos".
  • Facturación habilitada.

¿He perdido algo? ¿Hay algo más que deba hacer?

Gracias ..

Respuesta

8

El método de autorización de cuenta de servicio funciona bien con BigQuery. No necesita llamar al credential.refreshToken(). Asegúrese de que su archivo de clave privada se pueda leer desde su aplicación. He aquí un ejemplo:

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.bigquery.Bigquery; 
import com.google.api.services.bigquery.BigqueryScopes; 
import com.google.api.services.bigquery.Bigquery.Projects; 
import com.google.api.services.bigquery.model.*; 

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

public class BigQueryJavaServiceAccount { 

    public static void main(String[] args) throws IOException, InterruptedException, GeneralSecurityException { 

    final HttpTransport TRANSPORT = new NetHttpTransport(); 
    final JsonFactory JSON_FACTORY = new JacksonFactory(); 

    GoogleCredential credential = new GoogleCredential.Builder() 
     .setTransport(TRANSPORT) 
     .setJsonFactory(JSON_FACTORY) 
     .setServiceAccountId("[email protected]") 
     .setServiceAccountScopes(BigqueryScopes.BIGQUERY) 
     .setServiceAccountPrivateKeyFromP12File(new File("key.p12")) 
     .build(); 

    Bigquery bigquery = Bigquery.builder(TRANSPORT, JSON_FACTORY) 
     .setHttpRequestInitializer(credential) 
     .build(); 

    Projects.List projectListRequest = bigquery.projects().list(); 
    ProjectList projectList = projectListRequest.execute(); 
    List<ProjectList.Projects> projects = projectList.getProjects(); 
    System.out.println("Available projects\n----------------\n"); 
    for (ProjectList.Projects project : projects) { 
     System.out.format("%s\n", project.getProjectReference().getProjectId()); 
    } 
    } 
} 
+1

Gracias, Michael ... De manera vergonzosa, mi clave no se leía correctamente. Mi código funcionaba con una ruta absoluta para la clave. – Sprooose

+0

¿Dónde se guarda la llave? –

+0

@AakashParashar la clave debe guardarse localmente para que el script la lea, pero mantenla segura, como si fuera una contraseña que proporcionaba acceso a todo tu proyecto en la nube (que esencialmente es) –

0

Para la autenticación con una clave de cuenta de servicio con la Google Cloud BigQuery client libraries (Maven package) Puede use Application Default Credentials.

Primero configure la variable de entorno GOOGLE_APPLICATION_CREDENTIALS en la ruta completa a su cuenta de servicio archivo de clave JSON. En su código, cree el objeto de servicio de BigQuery utilizando la instancia predeterminada.

import com.google.cloud.bigquery.BigQuery; 
import com.google.cloud.bigquery.BigQueryOptions; 
... 
BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService(); 

Esta es la forma recomendada, ya que hace posible el uso del mismo código en múltiples entornos, como en Google Compute Engine, donde la cuenta de servicio está incorporado en lugar de utilizar un archivo de clave.

Como alternativa, puede desear construct a credentials object manually from a service account key file y utilizarlo para crear el objeto de servicio de BigQuery.

import com.google.auth.oauth2.GoogleCredentials; 
import com.google.auth.oauth2.ServiceAccountCredentials; 
import com.google.cloud.bigquery.BigQuery; 
import com.google.cloud.bigquery.BigQueryOptions; 

import java.io.File; 
import java.io.FileInputStream; 
import java.io.IOException; 

... 

// TODO: update to your key path. 
File credentialsPath = new File("service_account.json"); 

GoogleCredentials credentials; 
try (FileInputStream serviceAccountStream = new FileInputStream(credentialsPath)) { 
    credentials = ServiceAccountCredentials.fromStream(serviceAccountStream); 
} 

// Instantiate a client. 
BigQuery bigquery = 
    BigQueryOptions.newBuilder() 
     .setCredentials(credentials) 
     .build() 
     .getService(); 
Cuestiones relacionadas