授权给Google客户端

时间:2013-12-19 14:27:31

标签: java client google-bigquery google-cloud-storage

我正在编写一个用于为Bigquery和Google Cloud Storage创建授权的课程。在过去,我使用过已弃用的CredentialStore。我正在尝试使用DataStoreFactory,但我发现它允许我在需要Credential时仅使用StoredCredential。我知道可以从Credential转换为StoredCredential但我不确定如何将它们转换为相反的方向(StoredCredential to Credential)。我正在使用例如创建我的连接 Storage.Builder(HttpTransport传输,JsonFactory jsonFactory,HttpRequestInitializer httpRequestInitializer)

有人能指出我如何实现这个目标吗?谢谢!

2 个答案:

答案 0 :(得分:1)

在大多数情况下,无论您使用Credential,都可以使用StoredCredential。您将使用Credential只有一点,即在OAuth回调期间检索访问令牌。从那里,Credential可以转换为StoreCredential并存储到DataStore中。之后,存储和检索都可以使用StoredCredential。

但有些地方被StoredCredential无法使用。我刚刚遇到一个尝试创建Google云端硬盘API服务包装的人。

有一种方法可以使用GoogleCredential对象解决此问题,可以根据此答案从StoredCredential创建:Stored Credential from google api to be reused java

import com.google.api.client.auth.oauth2.StoredCredential;

public static GoogleCredential createGoogleCredential(StoredCredential storedCredential)
{
    HttpTransport httpTransport = new NetHttpTransport();
    JsonFactory jsonFactory = new JacksonFactory();
    GoogleCredential googleCredential = new GoogleCredential.Builder()
        .setTransport(httpTransport)
        .setJsonFactory(jsonFactory)
        .setClientSecrets("client_id", "client_secret").build();
    googleCredential.setAccessToken(storedCredential.getAccessToken());
    return googleCredential;
}

答案 1 :(得分:0)

我正在使用google-oauth-client-1.22.0.jar。

我的Java服务器具有静态Service Account凭据,可通过Google Cloud进行身份验证。

这是我使用的重要代码。

此处的关键是添加CredentialRefreshListener,当您成功进行身份验证后,Google OAuth客户端库将调用并为您提供一个StoredCredential对象,您可以对其进行序列化和存储。通过编写或实例化DataStore接口的实现,将其存储并检索到您选择的位置。您的DataStore实施是使用DataStoreFactory实施构建的。

构建GoogleCredential后,我可以从DataStore读取最后一个访问令牌,刷新令牌和到期日期。 如果访问令牌即将过期,则Google客户端API将使用它来登录。 当它即将到期时,或者这是第一次调用此代码时,Google Client API将调用刷新侦听器,它将存储第一个访问令牌,刷新令牌和到期日期。

import com.google.api.client.auth.oauth2.DataStoreCredentialRefreshListener;
import com.google.api.client.auth.oauth2.StoredCredential;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
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.IOUtils;
import com.google.api.client.util.store.AbstractDataStore;
import com.google.api.client.util.store.AbstractDataStoreFactory;
import com.google.api.client.util.store.DataStore;
import com.google.api.client.util.store.DataStoreFactory;
import com.google.api.services.storage.Storage;
import com.google.api.services.storage.StorageScopes;
import com.google.api.services.storage.model.StorageObject;

import java.io.IOException;
import java.io.Serializable;
import java.util.Base64;

public class StackOverflow {

  public static void main(final String... args) throws Exception {
    final String clientEmail = "todd.snider@aimless.com";
    final HttpTransport transport = GoogleNetHttpTransport.newTrustedTransport();
    final JsonFactory jsonFactory = new JacksonFactory();
    // This implementation generates an that stores and retrieves StoredCredential objects
    final DataStoreFactory dataStoreFactory = new AbstractDataStoreFactory() {
      @Override
      protected <V extends Serializable> DataStore<V> createDataStore(final String id) {
        return new MyDataStore<>(this, id);
      }
    };
    // construct a GoogleCredential object to access Google Cloud
    final GoogleCredential credential = new GoogleCredential.Builder()
        .setTransport(transport)
        .setJsonFactory(jsonFactory)
        .setServiceAccountId(clientEmail)
        .setServiceAccountScopes(StorageScopes.all())
        .setServiceAccountPrivateKey(readEncryptedPemFile())
        .setServiceAccountPrivateKeyId("___static_get_this_from_google_console___")
        .addRefreshListener(new DataStoreCredentialRefreshListener(clientEmail, dataStoreFactory))
        .build();
    // See I have an access token, refresh token and expiration date stored in my DataStore.
    // If so, set them on the GoogleCredential
    final StoredCredential storedCredential = StoredCredential.getDefaultDataStore(dataStoreFactory).get(clientEmail);
    if (storedCredential != null) {
      credential.setAccessToken(storedCredential.getAccessToken());
      credential.setRefreshToken(storedCredential.getRefreshToken());
      credential.setExpirationTimeMilliseconds(storedCredential.getExpirationTimeMilliseconds());
    }
    // Now I can use Google Cloud
    final Storage storage = new Storage.Builder(credential.getTransport(), credential.getJsonFactory(), credential).setApplicationName("Aimless").build();
    storage.objects().insert("soem bucket", new StorageObject());
  }

  private static class MyDataStore<V extends Serializable> extends AbstractDataStore<V> {

    MyDataStore(DataStoreFactory dataStoreFactory1, String id1) {
      super(dataStoreFactory1, id1);
    }

    @Override
    public DataStore<V> set(String key, V value) throws IOException {
      final String encoded = Base64.getEncoder().encodeToString(IOUtils.serialize(value));
      db.save(key, encoded);
      return this;
    }

    @Override
    public V get(String key) throws IOException {
      final String encoded = db.get(key);
      if (encoded == null) {
        return null;
      }
      return IOUtils.deserialize(Base64.getDecoder().decode(encoded));
    }

    // etc.
  }