1

I'm trying to load a .p12 file (Google certificate) from the filesystem in order to authenticate my application for Google Cloud Storage.

 Credential credential = new GoogleCredential.Builder()
            .setTransport(httpTransport)
            .setJsonFactory(jsonFactory)
            .setServiceAccountId("157264856793-sl14obknv58bi73m2co92oabrara9l8c@developer.gserviceaccount.com")
            .setServiceAccountPrivateKeyFromP12File(resourceLoader.getResource("classpath:google-auth.p12").getFile())
            .setServiceAccountScopes(scopes).build();

Unfortunately when trying to deploy the application (as a JAR onto Heroku) I get an error that I can't load a "file" from a JAR.

java.io.FileNotFoundException: class path resource [google-auth.p12] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/app/build/libs/Nitro.jar!/google-auth.p12

I've been advised to load the file as an inputstream as opposed to a file, but the GoogleCredential doesn't seem to have an appropriate method, only:

setServiceAccountPrivateKeyFromP12File(File file) method.

Advice apprecicated.

sparkyspider
  • 13,195
  • 10
  • 89
  • 133
  • You may be able to use [this answer](http://stackoverflow.com/q/18621508/4125191) to create a standard Java `PrivateKey` object, and then you may be able to use the `GoogleCredential.Builder.setServiceAccountPrivateKey()` method which accepts a `PrivateKey`. – RealSkeptic Aug 22 '15 at 11:05

2 Answers2

4

// Awful hack, but it worked! Load the input stream, create a temporary file from it, and then pass a reference of that to the Google API. I hope Google implements a method that accepts an InputStream soon.

    InputStream stream = resourceLoader.getResource("classpath:google-auth.p12").getInputStream();

    // Here is the juicy stuff...

    File tempFile = File.createTempFile("temp", "temp");
    IOUtils.copy(stream, new FileOutputStream(tempFile));

    // And the rest...

    HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
    JsonFactory jsonFactory = new JacksonFactory();

    List<String> scopes = new ArrayList<>();
    scopes.add(StorageScopes.CLOUD_PLATFORM);

    Credential credential = new GoogleCredential.Builder()
            .setTransport(httpTransport)
            .setJsonFactory(jsonFactory)
            .setServiceAccountId("157264856793-sl14obknv58bi73m2co92oabrara9l8c@developer.gserviceaccount.com")
            .setServiceAccountPrivateKeyFromP12File(tempFile)
            .setServiceAccountScopes(scopes).build();
sparkyspider
  • 13,195
  • 10
  • 89
  • 133
0

UPD: Try to use: setServiceAccountPrivateKeyFromP12File(new File(getClass().getResource("google-auth.p12").getFile()))

Oleksandr Loushkin
  • 1,479
  • 12
  • 21
  • `.getFile()` returns a String. `.setServiceAccountPrivateKeyFromP12File(File file()` expects a file. – sparkyspider Aug 22 '15 at 11:15
  • oh, yep. so it should be like this setServiceAccountPrivateKeyFromP12File(new File(getClass().getResource("google-auth.p12").getFile())) – Oleksandr Loushkin Aug 22 '15 at 11:42
  • No such luck, seems that because the internals of a .jar are not actually part of the normal file system, .getFile will never work. Fortunately, I managed to figure out a way to hack it by creating a temporary file. – sparkyspider Aug 22 '15 at 12:11