使用Oauth

时间:2015-07-03 15:16:31

标签: java google-oauth google-compute-engine google-api-java-client

我尝试使用Java连接到Google Compute Engine,但获得的异常对我来说并不重要。

example我跟随以下内容:

/** Authorizes the installed application to access user's protected data. */
private static Credential authorize() throws Exception {
  // load client secrets
  GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY,
      new InputStreamReader(CalendarSample.class.getResourceAsStream("/client_secrets.json")));
  // set up authorization code flow
  GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
      httpTransport, JSON_FACTORY, clientSecrets,
      Collections.singleton(CalendarScopes.CALENDAR)).setDataStoreFactory(dataStoreFactory)
      .build();
  // authorize
  return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
} 

为了获取包含凭据的json文件,我转到cloud.google.com,在控制台中转到我的应用,然后点击凭据,点击Create new ClientId,选择Service Account和{ {1}}。

这会下载JSON Key个文件。

_________.json中,我有以下代码来读取凭证文件:

public static void main(String ... args) throws Exception {

执行GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new FileReader("________9f.json")); 打印出包含密钥System.out.println(clientSecrets);private_key_idclient_emailclient_id的整个json文件。

现在,如果我继续使用示例代码:

type

这给了我以下堆栈跟踪:

  

线程中的异常" main" java.lang.IllegalArgumentException at   com.google.api.client.repackaged.com.google.common.base.Preconditions.checkArgument(Preconditions.java:76)     在   com.google.api.client.util.Preconditions.checkArgument(Preconditions.java:37)     在   com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets.getDetails(GoogleClientSecrets.java:82)     在   com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow $生成器。(GoogleAuthorizationCodeFlow.java:195)     在com.mycee.TestGoogle.main(TestGoogle.java:52)处   sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at   sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)     在   sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)     在java.lang.reflect.Method.invoke(Method.java:606)at   com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

Missing变量(现在都是静态变量)如下:

// set up authorization code flow
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
        httpTransport, JSON_FACTORY, clientSecrets,
                    Collections.singleton(ComputeScopes.COMPUTE)).setDataStoreFactory(dataStoreFactory).build();

// authorize
new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");

我试图通过Java管理我的Google Compute Engine实例,不知道我对Oath身份验证做错了吗?

更新

pom.xml按要求:

JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
FileDataStoreFactory dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR);
java.io.File DATA_STORE_DIR = new java.io.File(System.getProperty("user.home"), ".store/compute_engine_sample");

默认包中的TestGoogle.java(<?xml version="1.0" encoding="UTF-8" standalone="no"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.jvaas</groupId> <artifactId>jvaas-cloud</artifactId> <packaging>war</packaging> <version>1.0.0</version> <name>jVaaS Cloud</name> <properties> <jclouds.version>1.9.0</jclouds.version> <project.http.version>1.19.0</project.http.version> <project.oauth.version>1.19.0</project.oauth.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>com.google.http-client</groupId> <artifactId>google-http-client-jackson2</artifactId> <version>${project.http.version}</version> </dependency> <dependency> <groupId>com.google.oauth-client</groupId> <artifactId>google-oauth-client-jetty</artifactId> <version>${project.oauth.version}</version> </dependency> <dependency> <groupId>com.google.apis</groupId> <artifactId>google-api-services-compute</artifactId> <version>v1-rev27-1.19.0</version> </dependency> </dependencies> </project> 位于kots.json):

src/main/resources

完整的堆栈跟踪:

import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.compute.Compute;
import com.google.api.services.compute.ComputeScopes;
import com.google.api.services.compute.model.Instance;
import com.google.api.services.compute.model.InstanceList;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;

public class TestGoogle {

    private static final java.io.File DATA_STORE_DIR = new java.io.File(System.getProperty("user.home"), ".store/compute_engine_sample");
    private static FileDataStoreFactory dataStoreFactory;
    private static HttpTransport httpTransport;
    private static final String zoneName = "us-central1-a";
    private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
    private static final List<String> SCOPES = Arrays.asList(ComputeScopes.COMPUTE_READONLY);

    public static void main(String... args) throws Exception {

        httpTransport = GoogleNetHttpTransport.newTrustedTransport();
        dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR);

        InputStream in = TestGoogle.class.getResourceAsStream("/kots.json");

        GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
        GoogleAuthorizationCodeFlow flow = // <- fails here
                new GoogleAuthorizationCodeFlow.Builder(
                        httpTransport, JSON_FACTORY, clientSecrets, SCOPES)
                        .setDataStoreFactory(dataStoreFactory)
                        .setAccessType("online").setApprovalPrompt("auto")
                        .build();

        new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");

    }
}

反编译相关的类文件,这些是相关的代码片段:

GoogleAuthorizationCodeFlow.java:195

Exception in thread "main" java.lang.IllegalArgumentException
    at com.google.api.client.repackaged.com.google.common.base.Preconditions.checkArgument(Preconditions.java:76)
    at com.google.api.client.util.Preconditions.checkArgument(Preconditions.java:37)
    at com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets.getDetails(GoogleClientSecrets.java:82)
    at com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow$Builder.<init>(GoogleAuthorizationCodeFlow.java:195)
    at TestGoogle.main(TestGoogle.java:38)

GoogleClientSecrets.java:82

public Builder(HttpTransport transport, JsonFactory jsonFactory, GoogleClientSecrets clientSecrets, Collection<String> scopes) {
    super(BearerToken.authorizationHeaderAccessMethod(), transport, jsonFactory, new GenericUrl("https://accounts.google.com/o/oauth2/token"), new ClientParametersAuthentication(clientSecrets.getDetails().getClientId(), clientSecrets.getDetails().getClientSecret()), clientSecrets.getDetails().getClientId(), "https://accounts.google.com/o/oauth2/auth");
    this.setScopes(scopes);
}

Preconditions.java:37

public GoogleClientSecrets.Details getDetails() {
    Preconditions.checkArgument(this.web == null != (this.installed == null));
    return this.web == null?this.installed:this.web;
}

Preconditions.java:76

public static void checkArgument(boolean expression) {
    com.google.api.client.repackaged.com.google.common.base.Preconditions.checkArgument(expression);
}

kots.json,屏蔽了所有敏感数据:

public static void checkArgument(boolean expression) {
    if(!expression) {
        throw new IllegalArgumentException();
    }
}
当我点击cloud.google.com

中的此按钮时,会生成

kots.json

enter image description here

更新,似乎我的json文件不正确,这种格式为我修复了(复制自@We Borg的对话):

{
  "private_key_id": "________________________________________",
  "private_key": "-----BEGIN PRIVATE KEY-----\n__________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________\n-----END PRIVATE KEY-----\n",
  "client_email": "_____________________________________________@developer.gserviceaccount.com",
  "client_id": "_____________________________________________.apps.googleusercontent.com",
  "type": "service_account"
}

从中下载它的正确位置是创建一个新的客户端ID并选择isntalled应用程序。

2 个答案:

答案 0 :(得分:4)

我从Google Cloud下载的原始json秘密文件存在完全相同的问题。

通过设置包含json秘密文件路径的env变量

,一切正常
set GOOGLE_APPLICATION_CREDENTIALS "secret.json path"

并运行此行:

GoogleCredential credential = GoogleCredential.getApplicationDefault();

但是当我想把我的秘密文件作为我项目中的资源包括在内时,出现了像你这样的问题。

所以我终于发现这条简单的线解决了这个问题:

GoogleCredential credential =
    GoogleCredential.fromStream(MyClass.class.getResourceAsStream("/client_secrets.json"));

希望有所帮助

答案 1 :(得分:2)

实际上你不是,我受到类似Google Go Drive问题的骚扰,但这段代码对我有用。我知道你会认为你的代码是一样的,但只是尝试一下。

private static final List<String> SCOPES =
            Arrays.asList(DriveScopes.DRIVE);
     @Override
        public Credential authorize() throws IOException {
            InputStream in =
                    DriveQuickstartImpl.class.getResourceAsStream("/client_secret.json");
            GoogleClientSecrets clientSecrets =
                    GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));

            GoogleAuthorizationCodeFlow flow =
                    new GoogleAuthorizationCodeFlow.Builder(
                            HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
                            .setDataStoreFactory(DATA_STORE_FACTORY)
                            .setAccessType("online").setApprovalPrompt("auto")
                            .build();
            Credential credential = new AuthorizationCodeInstalledApp(
                    flow, new LocalServerReceiver()).authorize("user");
            if(credential!=null && credential.getRefreshToken() != null){
                storeCredentials(credential);
            }
           return credential;

        }

如果它不起作用,请告诉我,我将删除它,我的client_secret在资源文件夹中。