I have an application that gets deployed into Tomacat servlet containers. I have a background job that gets run where I make a call to Google Analytics that is authorized using a Service Account's PK12 file.
I don't have access to the container's file system, so I deploy the pk12 file in my WAR's WEB-INF/ . I don't anticipate being given access to add any authentication keys into the Servlet Container's host's system registry/keychain.
GoogleCredential's Buidler.setServiceAccountPrivateKeyFromP12File(File) only takes java.io.File, so I ended up doing something that is kludgey to authorize. I open the PK12 file using serveltContenxt.getResourceAsStream and copy it's contents to a temporary file which I pass into the Credential's builder.
When I tried to do
java.io.File p12File = new java.io.File(servletContext.getResource('...pk12.file...').getFile())
there was an error saying that the File doesn't exists because it tries to open a file on disk while the pk12 file is either not unbundled or the URI that comes back isn't the correct one for the file.
What's the right way to do this? I'm new to the world of PrivateKey authentication and the google client api.
Here's my currently working code:
// create file because credential only takes a File object
final File p12File = File.createTempFile("xxx", ".tmp");
p12File.deleteOnExit();
InputStream in = servletContext.getResourceAsStream("...pk12.file...");
FileOutputStream out = new FileOutputStream(p12File);
org.apache.commons.io.IOUtils.copy(in, out);
out.flush();
out.close();
in.close();
GoogleCredential credential = new GoogleCredential.Builder().setTransport(httpTransport)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId("xxxxxxx@developer.gserviceaccount.com")
.setServiceAccountScopes(Collections.singleton(AnalyticsScopes.ANALYTICS_READONLY))
.setServiceAccountPrivateKeyFromP12File(p12File)
.build();
p12File.delete();
// Set up and return Google Analytics API client.
this.analytics = new Analytics.Builder(httpTransport, JSON_FACTORY, credential).setApplicationName("mybackgroundprocess/1.0").build();
thanks
I found the same problem was answered here: Getting a PrivateKey object from a .p12 file in Java
I just had to create a private key from the resource
InputStream in = servletContext.getResourceAsStream("p12.file");
PrivateKey privateKey = SecurityUtils.loadPrivateKeyFromKeyStore(SecurityUtils.getPkcs12KeyStore(), in, "notasecret", "privatekey", "notasecret");
and then call
GoogleCredential.Builder.setServiceAccountPrivateKey(PrivateKey privateKey)