2012-08-06 30 views
5

Sto tentando di utilizzare oauth API per autenticare un account di servizio google tramite l'API Java. Spero di usarlo per accedere a Google Bigquery. Ricevo una "sovvenzione non valida" restituita dalle mie richieste API.Autenticazione dell'API di Google con un account di servizio con API Java

Ecco il codice, che è una copia di un esempio di autenticazione di base (che non era per BigQuery .. ma un'altra API di 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 è l'indirizzo email della forma: XXXXXXX @ developer.gserviceaccount.com

Se rimuovo la riga credential.refreshToken(), fallisce negli elenchiDataset sulla prima chiamata a Bigquery ... Altrimenti fallisce su credential.refreshToken() .. con lo stesso errore .

BigQuery non accetta l'autenticazione dell'account di servizio?

Credo di aver fatto tutto correttamente attraverso la console API. Ho:

  • Accesso acceso all'API di Big Query attivata.
  • Creato un account di servizio nella scheda "Accesso API".
  • Scaricata la mia chiave privata (a cui si fa riferimento dal codice precedente).
  • Dato che l'utente dell'account di servizio "può modificare" l'accesso nella scheda "Teams".
  • Fatturazione attivata.

Ho perso qualcosa? C'è qualcos'altro che devo fare?

Grazie ..

risposta

8

Il metodo di autorizzazione account di servizio funziona bene con BigQuery. Non è necessario chiamare lo credential.refreshToken(). Assicurati che il file della tua chiave privata possa essere letto dalla tua applicazione. Ecco un esempio:

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

Grazie, Michael .. In modo imbarazzante, la mia chiave non è stata letta correttamente. Il mio codice ha funzionato con un percorso assoluto per la chiave. – Sprooose

+0

Dove dovrebbe essere conservata la chiave? –

+0

@AakashParashar la chiave deve essere conservata in locale affinché lo script possa leggerla, ma tenerla al sicuro, come se si trattasse di una password che forniva l'accesso all'intero progetto cloud (che in sostanza è) –

0

Per l'autenticazione con una chiave account di servizio con il Google Cloud BigQuery client libraries (Maven package) si può use Application Default Credentials.

Prima impostare la variabile di ambiente GOOGLE_APPLICATION_CREDENTIALS sul percorso completo del file chiave JSON dell'account di servizio. Nel codice, creare l'oggetto del servizio BigQuery utilizzando l'istanza predefinita.

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

Questo è il metodo consigliato, in quanto rende possibile l'uso lo stesso codice in più ambienti, come ad esempio su Google Compute Engine, in cui è incorporata l'account del servizio piuttosto che utilizzare un file di chiave.

In alternativa, è possibile utilizzare construct a credentials object manually from a service account key file e utilizzarlo per creare l'oggetto del servizio 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(); 
Problemi correlati