2012-08-06 200 views
5

我正在尝试使用oauth API通过Java API对Google服务帐户进行身份验证。我希望用它来访问Google BigQuery。我收到我的API请求返回的“无效授权”。使用Java API对服务帐户进行身份验证Google API

下面是代码,这是一个基本的身份验证实例的副本(这是不是BIGQUERY ..但另一个谷歌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是形式的电子邮件地址:XXXXXXX @ developer.gserviceaccount.com

如果我删除了credential.refreshToken()行,它会在第一次调用BigQuery时在列表数据集中失败......否则它会在credential.refreshToken()上失败,并且出现相同的错误。

BigQuery不接受服务帐户身份验证吗?

我相信我已经通过API控制台正确地做了所有事情。我有:

  • 打开对Big Query API的访问。
  • 在“API访问”选项卡下创建一个服务帐户。
  • 下载我的私钥(从上面的代码中引用)。
  • 鉴于我的服务帐户用户在“团队”选项卡下可以“编辑”访问权限。
  • 启用帐单。

我错过了什么吗?还有什么我需要做的?

谢谢..

回答

8

服务帐户授权方法工作得很好,与BigQuery。您无需致电credential.refreshToken()。确保您的私钥文件可以从您的应用程序中读取。这里有一个例子:

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

谢谢,迈克尔..尴尬的是,我的钥匙没有被正确读取。我的代码与密钥的绝对路径一起工作。 – Sprooose 2012-08-06 22:11:37

+0

钥匙应放在哪里? – 2016-03-09 06:59:58

+0

@AakashParashar密钥必须保存在本地供脚本读取,但保持安全,就好像它是一个可以访问整个云计算项目的密码(实质上是密码) – 2016-03-09 16:49:36

0

要与该Google Cloud BigQuery client librariesMaven package)服务帐户键即可use Application Default Credentials验证。

首先将GOOGLE_APPLICATION_CREDENTIALS环境变量设置为服务帐户JSON密钥文件的完整路径。在您的代码中,使用默认实例创建BigQuery服务对象。

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

这是推荐的方式,因为它使得可以使用相同的代码在多种环境中,如谷歌计算引擎,服务帐户是内置的,而不是使用一个密钥文件。

或者,您可能希望construct a credentials object manually from a service account key file并使用它创建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(); 
相关问题