Search code examples
javaprivate-keygoogle-oauth

Use a .p12 File from classpath for GoogleCredential


I am making a java command line application packaged in a single JAR file that uses some of Google's API.

I need to set up a GoogleCredential object from a private key "Credentials.p12".

GoogleCredential credential = new GoogleCredential.Builder()
                    .setTransport(httpTransport)
                    .setJsonFactory(jsonFactory)
                    .setServiceAccountId("[email protected]")
                    .setServiceAccountScopes(Arrays.asList(DirectoryScopes.ADMIN_DIRECTORY_GROUP, DirectoryScopes.ADMIN_DIRECTORY_USER, DirectoryScopes.ADMIN_DIRECTORY_ORGUNIT))
                    .setServiceAccountUser(emailAccount)
                    //THE CODE BELOW IS IMPORTANT: I need to change this
                    .setServiceAccountPrivateKeyFromP12File(new File("Credentials.p12"))
                    .build();

        directory = new Directory.Builder(httpTransport, jsonFactory, credential)
                .setApplicationName("My Cmd App")
                .build();

Right now I was able to make it work, but the file "Credentials.p12" is located outside the packaged JAR file.

How do I make it work using a p12 file from inside the JAR?

From this documentation, the only other alternative that I think I can use is the method variant that uses a PrivateKey object. I am thinking of using InputStream to get the p12 file from the classpath:

InputStream is = this.getClass().getResourceAsStream("Credentials.p12");

I absolutely have no idea how to do that.

Before you answer, please make sure that you have experience using the Google OAuth2 library. And Please, no hacks like copying the resource to a temporary file: the singular version of Credential.p12 should remain inside the JAR for a reason.


Solution

  • After digging through the GoogleCredential.Builder class source code I realized the following:

    • the password for the p12 file generated from Google's developer console is always "notasecret" as well as the password for the alias
    • the alias for the private key is always "privatekey"

    using the following code to build the private key from the resource InputStream:

    KeyStore keystore = KeyStore.getInstance("PKCS12");
    keystore.load(this.getClass().getClassLoader().getResourceAsStream("Credentials.p12"), "notasecret".toCharArray());
    PrivateKey pk = (PrivateKey)keystore.getKey("privatekey", "notasecret".toCharArray());
    

    I was able to load the private key into the GoogleCredential Builder:

    GoogleCredential credential = new GoogleCredential.Builder()
                        .setTransport(httpTransport)
                        .setJsonFactory(jsonFactory)
                        .setServiceAccountId("[email protected]")
                        .setServiceAccountScopes(Arrays.asList(DirectoryScopes.ADMIN_DIRECTORY_GROUP, DirectoryScopes.ADMIN_DIRECTORY_USER, DirectoryScopes.ADMIN_DIRECTORY_ORGUNIT))
                        .setServiceAccountUser(emailAccount)
                        .setServiceAccountPrivateKey(pk) //<----THIS
                        .build();