授权给Google客户端

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

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

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

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

有一种方法可以通过GoogleCredential对象来解决这个问题,它可以根据以下答案从StoredCredential创建: 来自google api的存储凭据可以重用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; } 

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

我有一个带有静态服务帐户凭据的Java服务器,可通过Google Cloud进行身份validation。

这是我使用的重要代码。

这里的关键是添加一个CredentialRefreshListener ,当您成功进行身份validation时,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  DataStore 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 extends AbstractDataStore { MyDataStore(DataStoreFactory dataStoreFactory1, String id1) { super(dataStoreFactory1, id1); } @Override public DataStore 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. }