2012-08-06 12 views
5

Ich versuche, die oauth-API zu verwenden, um ein Google-Dienstkonto über die Java-API zu authentifizieren. Ich hoffe, damit auf Google BigQuery zugreifen zu können. Ich erhalte eine "ungültige Genehmigung", die von meinen API-Anfragen zurückgegeben wird. HierAuthentifizieren von Google API mit einem Dienstkonto mit Java-API

ist der Code, der eine Kopie eines Standardauthentifizierung Beispiel (das nicht für BigQuery war .. aber eine andere Google API):

/** 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 ist die E-Mail-Adresse der Form: XXXXXXX @ developer.gserviceaccount.com

Wenn ich die credential.refreshToken() Zeile entfernen, schlägt es in den listsDatasets beim ersten Aufruf von Bigquery fehl ... Andernfalls schlägt credential.refreshToken() ... mit demselben Fehler fehl .

Akzeptiert BigQuery die Authentifizierung des Dienstkontos nicht?

Ich glaube, ich habe alles richtig über die API-Konsole gemacht. Ich habe:

  • Turned-Zugriff auf die große Abfrage-API auf.
  • Erstellt ein Dienstkonto auf der Registerkarte "API-Zugriff".
  • Heruntergeladen mein privater Schlüssel (der aus dem obigen Code verwiesen wird).
  • Mit meinem Dienstkonto Benutzer "bearbeiten" Zugriff auf der Registerkarte "Teams".
  • Aktivierte Fakturierung.

Habe ich etwas verpasst? Gibt es noch etwas, was ich tun muss?

Dank ..

Antwort

8

Verfahren Kontenberechtigung Service arbeitet mit BigQuery gut. Sie müssen credential.refreshToken() nicht anrufen. Stellen Sie sicher, dass Ihre private Schlüsseldatei aus Ihrer Anwendung gelesen werden kann. Hier ein Beispiel:

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

Danke, Michael .. Peinlich, mein Schlüssel wurde nicht richtig gelesen. Mein Code arbeitete mit einem absoluten Pfad für den Schlüssel. – Sprooose

+0

Wo sollte der Schlüssel aufbewahrt werden? –

+0

@AakashParashar der Schlüssel muss lokal aufbewahrt werden, damit das Skript es lesen kann, aber es sicher halten, als wäre es ein Passwort, das Zugriff auf Ihr gesamtes Cloud-Projekt bietet (was es im Wesentlichen ist) –

0

Zur Authentifizierung mit einem Dienstkonto Schlüssel mit den Google Cloud BigQuery client libraries (Maven package) können Sie use Application Default Credentials.

Zuerst setzen Sie die GOOGLE_APPLICATION_CREDENTIALS Umgebungsvariable auf den vollständigen Pfad zu Ihrem Dienstkonto JSON-Schlüsseldatei. Erstellen Sie in Ihrem Code das BigQuery-Dienstobjekt mit der Standardinstanz.

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

Dies ist die empfohlene Methode, da sie es möglich, zu verwenden den gleichen Code in mehreren Umgebungen, wie zum Beispiel auf Google Compute Engine, wo das Dienstkonto eher ist eingebaut machen als eine Schlüsseldatei.

Alternativ können Sie auch construct a credentials object manually from a service account key file verwenden und das BigQuery-Dienstobjekt erstellen.

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();