使用 GAE 服务帐户 JSON 密钥
Posted
技术标签:
【中文标题】使用 GAE 服务帐户 JSON 密钥【英文标题】:Use GAE Service Account JSON key 【发布时间】:2014-09-07 00:12:42 【问题描述】:我在 GAE 中有一个应用程序,我正在使用服务帐户来调用一些谷歌服务。当我在仪表板中创建服务帐户时,向我提供了一个 JSON 密钥。 json的内容是这样的:
"private_key_id": "bar-foo",
"private_key": "-----BEGIN PRIVATE KEY-----foo-bar\n-----END PRIVATE KEY-----\n",
"client_email": "foo-bar@developer.gserviceaccount.com",
"client_id": "bar-foo.apps.googleusercontent.com",
"type": "service_account"
如何在我的 java 代码中使用此 private_key 来生成 GoogleCredential 对象?
我可以使用setServiceAccountPrivateKeyFromP12File
方法做到这一点,但为此我需要创建一个 p12 文件并将其存储在某处。使用 json 私钥,我可以在我的属性文件中配置它。
我在GoogleCredential.Builder
中找到了一个setServiceAccountPrivate
方法,它接收一个PrivateKey 对象作为参数,但我不知道如何从json 中的值生成这个对象。我发现的所有示例都使用 p12 文件。
【问题讨论】:
【参考方案1】:由于这个问题仍在获得意见并且没有公认的答案,这里有一个如何使用 JSON 密钥和谷歌 API 客户端库的示例,略微改编自官方文档部分“Using OAuth 2.0 with the Google API Client Library for Java”:
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
...
// Build service account credential.
GoogleCredential credential = GoogleCredential.fromStream(MyClass.class.getResourceAsStream("/MyProject-1234.json"))
.createScoped(Collections.singleton(PlusScopes.PLUS_ME));
// Set up global Plus instance.
plus = new Plus.Builder(httpTransport, jsonFactory, credential)
.setApplicationName(APPLICATION_NAME).build();
您可以放置您的密钥文件,例如。 'MyProject-1234.json' 到 /src/main/resources 和上面的 'MyClass' 是指包含您的方法的父类的名称。
【讨论】:
你把“MyProject-1234.json”放在你的项目结构中的什么位置? 我意识到该示例仅包含一个通用文件读取示例,因此我编辑了我的答案以包含一种适用于 App Engine 的方式。这实际上适用于任何 servlet 应用程序,并且还有其他方法可以做到这一点,例如。将其放在“WEB-INF”下并使用 getServletContext().getResourceAsStream("/WEB-INF/MyProject-1234.json")。 将私钥文件放在WEB-INF下不会造成安全问题吗? WEB-INF 不是公共文档树的一部分,不应该提供给客户,但是对于偏执狂(包括我自己),我建议坚持使用 /src/main/resources。我提到它是为了完整性,因为它是在 GAE 中读取文件资源的支持方式。 fromStream 方法不可见【参考方案2】:您应该在创建项目时使用 GAE 代表您创建的内置服务帐户。您可以在此处查看如何使用它的示例:https://developers.google.com/bigquery/authorization#service-accounts-appengine
您可以从这里的其他问题中找到更多关于服务帐户的信息:https://***.com/a/24478017/700188(它适用于 python,但应该有相应的 java 文章)
编辑:
这是一篇关于使用内置服务帐户身份与 Google 的 API 通信的 Google AppEngine 文档:
https://developers.google.com/appengine/docs/java/appidentity/#Java_Asserting_identity_to_Google_APIs
没有必要为 GAE 使用单独的服务帐户,因为已经为您提供了一个。
编辑 2
不确定 JSON 文件中的私钥是否与 p12 文件中的私钥相同,但如果是,您可以尝试类似(抱歉,我的 Java 可能有点生锈):
import com.google.api.client.util.SecurityUtils;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.PrivateKey;
// Read the JSON Private key as a byte[] array into bytes
PrivateKey serviceAccountPrivateKey = SecurityUtils.getRsaKeyFactory().generatePrivate(new PKCS8EncodedKeySpec(bytes));
【讨论】:
不确定我们在这里讨论的是否相同。 您是否尝试从您的 GAE 应用访问通过 Cloud Console 启用的 Google API? 是的,我正在使用通过控制台启用的 Google API。 那么我认为您应该使用您在 GAE 应用中获得的服务帐户,这样您就不必担心 JSON 和 P12 文件之类的事情。 您可以通过该项目的 Cloud Console 中的“权限”菜单将您的 GAE 应用的服务帐户添加到该项目。您的服务帐户的格式应为your_app_id@appspot.gserviceaccount.com
以上是关于使用 GAE 服务帐户 JSON 密钥的主要内容,如果未能解决你的问题,请参考以下文章