Java中的Google API身份验证,不使用环境变量

时间:2017-01-05 10:34:38

标签: java google-api

我已经设置了一个简单的测试应用来与Google的Natural Language API进行互动。我created a service account,并下载了JSON凭据。我在本地开发机器上运行,因此我将GOOGLE_APPLICATION_CREDENTIALS环境变量设置为指向JSON文件。为了清楚起见,这可行:应用程序成功进行了一些API调用并显示结果。

我想删除对环境变量的依赖。如何在应用程序中使用JSON文件(或任何其他方法)的已知位置来创建具有这些凭据的LanguageServiceClient

5 个答案:

答案 0 :(得分:3)

您可以注册如下:

DatastoreOptions options = DatastoreOptions.newBuilder()
  .setProjectId(PROJECT_ID)
  .setAuthCredentials(AuthCredentials.createForJson(
    new FileInputStream(PATH_TO_JSON_KEY))).build();

这有帮助吗?

答案 1 :(得分:2)

我们使用服务帐户+ GoogleCredential.Builder - (请注意,此示例使用p12格式的凭据文件);示例如下:

 private GoogleCredential authorize() throws IOException, GeneralSecurityException
{
    return new GoogleCredential.Builder()
    .setTransport(HTTP_TRANSPORT)
    .setJsonFactory(JSON_FACTORY)
    .setServiceAccountId(serviceAccount)
    .setServiceAccountScopes(SCOPES)
    .setServiceAccountUser(serviceAccountUser)
    // variable p12File is a String w/ path to the .p12 file name
    .setServiceAccountPrivateKeyFromP12File(new java.io.File(p12File))
      .build();
}

答案 2 :(得分:1)

这看起来像是一个较老的帖子,但是分享了我们的发现以获得它的价值。

此示例适用于Google ImageAnnotatorClient,但我非常确定它与LanguageServiceClient非常相似。

老派谷歌图书馆(P12档案时代)使用GoogleCredential与新版GoogleCredentials。它们看起来很相似。深入了解Type层次结构,我发现了一个看起来很复杂的FixedCredentialsProvider。

这对我们有用,我们启动了Google Vision API并使用现有的P12文件运行,没有环境变量。看起来谷歌希望我们远离这一点,所以不要长期推荐这种方法。

// old-school Google Authentication
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();

// Spring code
String pemFile = "yourPemFile.p12";
Resource r = new ClassPathResource(pemFile);
String serviceAccountEmail = "xxxx@xxxx.iam.gserviceaccount.com";

// com.google.api.client.googleapis.auth.oauth2.GoogleCredential.Builder
Builder credentialBuilder = new GoogleCredential.Builder()
            .setTransport(httpTransport)
            .setJsonFactory(jsonFactory)
            .setServiceAccountId(serviceAccountEmail)
            .setServiceAccountPrivateKeyFromP12File(r.getFile());

// Cloud API endpoints, make sure that the API is enabled
Collection<String> scopes = Collections.singleton("https://www.googleapis.com/auth/cloud-vision");
GoogleCredential credential = credentialBuilder
            .setServiceAccountScopes(scopes).build();

// copy over key values, note the additional "s", set some expiry
// com.google.auth.oauth2.GoogleCredentials 
GoogleCredentials sac = ServiceAccountCredentials.newBuilder()
            .setPrivateKey(gc.getServiceAccountPrivateKey())
            .setPrivateKeyId(gc.getServiceAccountPrivateKeyId())
            .setClientEmail(gc.getServiceAccountId())
            .setScopes(scopes)
            .setAccessToken(new AccessToken(gc.getAccessToken(), new LocalDate().plusYears(1).toDate()))
            .build();

// Latest generation Google libs, GoogleCredentials extends Credentials
CredentialsProvider cp = FixedCredentialsProvider.create(sac);
ImageAnnotatorSettings settings = ImageAnnotatorSettings.newBuilder().setCredentialsProvider(cp).build();
ImageAnnotatorClient googleApi = ImageAnnotatorClient.create(settings);

答案 3 :(得分:1)

根据上面 tokyohans 回答的建议,我可以确认这适用于LanguageServiceClient:

    // old-school Google Authentication     
    GoogleCredential credential = null;
    credential = GoogleCredential.fromStream(new FileInputStream("google.json"));

    Collection<String> scopes = Collections.singleton("https://www.googleapis.com/auth/cloud-language");

    if (credential.createScopedRequired()) {
          credential = credential.createScoped(scopes);
    }

    // copy over key values, note the additional "s", set some expiry
    // com.google.auth.oauth2.GoogleCredentials 
    GoogleCredentials sac = ServiceAccountCredentials.newBuilder()
                .setPrivateKey(credential.getServiceAccountPrivateKey())
                .setPrivateKeyId(credential.getServiceAccountPrivateKeyId())
                .setClientEmail(credential.getServiceAccountId())
                .setScopes(scopes)
                .setAccessToken(new AccessToken(credential.getAccessToken(), new LocalDate().plusYears(1).toDate()))
                .build();

    // Latest generation Google libs, GoogleCredentials extends Credentials
    CredentialsProvider cp = FixedCredentialsProvider.create(sac);
    LanguageServiceSettings settings = (LanguageServiceSettings) LanguageServiceSettings.newBuilder().setCredentialsProvider(cp).build();
    return LanguageServiceClient.create(settings);

答案 4 :(得分:0)

您始终可以将完整的json文件作为String传递,如下所示:

        CredentialsProvider credentialsProvider;
        String credentials = "[YOUR JSON FILE CONTENT]";

        try {

            credentialsProvider
                    = FixedCredentialsProvider.create(
                            ServiceAccountCredentials.fromStream(new ByteArrayInputStream(credentials.getBytes())));          

        } catch (IOException ex) {
            Logger.getLogger(GoogleNLPService.class.getName()).log(Level.SEVERE, null, ex);
        }

        LanguageServiceSettings.Builder languageServiceSettingsBuilder
                = LanguageServiceSettings.newBuilder();

        LanguageServiceSettings languageServiceSettings = languageServiceSettingsBuilder.setCredentialsProvider(credentialsProvider).build();

        List<NamedEntity> entities = new ArrayList<>();
        try (LanguageServiceClient language = LanguageServiceClient.create(languageServiceSettings)) {

         ...

        }

或者,您可以将json文件放在resources文件夹中,然后将其读取为:

    credentialsProvider
            = FixedCredentialsProvider.create(
                    ServiceAccountCredentials.fromStream(new FileInputStream("./src/main/resources/FILENAME.json")));

但是,当我在Heroku中上传应用程序时,此相对路径不起作用。因此,我决定使用String解决方案。