Blog

How to authenticate to Google Drive in Java

24 Dec, 2023
Xebia Background Header Wave

Most examples of access to Google Drive from Java using the Google Client SDKs, authenticate with the deprecated GoogleCredential class and a service account key file. We advise against the use of service account private key file as these files contain a private key in clear text with an expiration date set to January 1st, in the year 10000. Instead, use the shorted-lived credentials provided by the Google Cloud SDK, App Engine, Cloud Shell, Compute Engine, Cloud Run or GKE workload identity instead.

How to authenticate to Google in Java

To authenticate to Google Drive or any other Google Cloud Platform API in Java, use the method getApplicationDefault as shown below:

public class List {
    public static void main(String[] args) throws IOException, GeneralSecurityException {
        GoogleCredentials credentials = GoogleCredentials
            .getApplicationDefault()                        // get ADC
            .createScoped(
              ImmutableSet.of(
                "https://www.googleapis.com/auth/drive"));  // add scope(s)

        Drive service = new Drive
            .Builder(
                  GoogleNetHttpTransport.newTrustedTransport(),
                  GsonFactory.getDefaultInstance(),
                  new HttpCredentialsAdapter(credentials))    // wrap credentials
            .setApplicationName("list")
            .build();                        
}

In line 3-6 you see that we request the application default credentials (ADC) with the drive scope. On line 13, you see that we pass these credentials into the Drive builder wrapped in the HttpCredentialsAdapter, so that they can be used with the Drive REST API.

The method getApplicationDefault ensures your application works both with and without a service account key file. It will search for credentials in the following order:

  • Service account key file point to by $GOOGLE_APPLICATION_CREDENTIALS
  • Google Cloud SDK application default credentials
  • Google App Engine built-in credentials
  • Google Cloud Shell built-in credentials
  • Google Compute Engine built-in credentials

So, this code will now work on your local machine, in Google App Engine, in Google Cloud Shell, on a Compute instance, in a Cloud Run service and a GKE pod.

Running locally

Before you can run this code from your local machine, type the following commands:

gcloud auth application-default login \
    --scopes https://www.googleapis.com/auth/drive
gcloud auth application-default set-quota-project $GOOGLE_CLOUD_PROJECT

That is all there is to it, without any private key file!

Running in a local container

TO run your application in a container on your local machine, mount the gcloud configuration directory as shown below:

docker run --volume $HOME/.config/gcloud:/root/.config/gcloud $IMAGE_NAME

Note that the .config directory should be mounted in the home directory of the user running the entrypoint command.

The application can now also run on a virtual machine. We will show that in the next paragraph.

Running on a virtual machine

When you want to run this code on a virtual machine, create a service account, associate it with the machine and pecify the allowed scopes. This is shown in the terraform snippet below:

resource "google_compute_instance" "gdrive-accessor" {
  name         = "gdrive-accessor"

  service_account {
    email  = google_service_account.gdrive-accessor.email           // run-as service account
    scopes = [
      "https://www.googleapis.com/auth/drive",                      // extend allowed scope
      "https://www.googleapis.com/auth/cloud-platform"
    ]
  }
  ... 
}

resource "google_service_account" "gdrive-accessor" {
  account_id   = "gdrive-accessor"
  display_name = "Access to the Google Drive"
}

resource "google_project_iam_member" "gdrive-accessor" {
  for_each = toset(["roles/logging.logWriter", "roles/monitoring.metricWriter"])
  member   = google_service_account.gdrive-accessor.member
  role     = each.value
}

On line 5, the service account is bound to the virtual machine. On line 6-9 the scopes are added. It is also possible to write terraform code to grant access to the created service account on the desired google drive folder. I will save that for another blog.

Use credentials for other Google APIs

You can use the credentials in any other Google API too. For example, The following snippet shows how the credentials is used to connect to Google BigQuery:

        BigQuery bigquery = BigQueryOptions
                .newBuilder()
                .setCredentials(credentials)        // use credentials
                .setProjectId(project)
                .build()
                .getService();

Conclusion

When accessing Google Drive from Java we recommend to use the method getApplicationDefault, as this provides you with a safe and easy way to connect to any Google API without the use of a service account key file.

You can find a working example on github.


Image by Mike from Pixabay

Mark van Holsteijn
Mark van Holsteijn is a senior software systems architect at Xebia Cloud-native solutions. He is passionate about removing waste in the software delivery process and keeping things clear and simple.
Questions?

Get in touch with us to learn more about the subject and related solutions

Explore related posts