title: 401 response when athenticating via Service Account and OAuth2 to GoogleDrive
body: <p>I seem to have hit a wall trying to get a Java application to list of files stored in my GoogleDrive folder. The </p>
  
  <p>I have a project setup in the Developer Console.
  I have enabled for that project the Drive API
  I have create Auth credentials for a Service Account - and am using the P12 key produced.</p>
  
  <p>My code looks like this :</p>
  
  <pre><code>import com.google.api.client.auth.oauth2.Credential;
  import com.google.api.client.auth.oauth2.CredentialRefreshListener;
  import com.google.api.client.auth.oauth2.TokenErrorResponse;
  import com.google.api.client.auth.oauth2.TokenResponse;
  import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
  import com.google.api.client.http.HttpTransport;
  import com.google.api.client.http.javanet.NetHttpTransport;
  import com.google.api.client.json.JsonFactory;
  import com.google.api.client.json.jackson2.JacksonFactory;
  import com.google.api.services.drive.Drive;
  import com.google.api.services.drive.DriveScopes;
  import com.google.api.services.drive.model.File;
  import com.google.api.services.drive.model.FileList;
  
  import java.io.IOException;
  import java.security.GeneralSecurityException;
  import java.util.Collections;
  import java.util.List;
  
  public class GoogleDriveTest {
  
      /** Global instance of the JSON factory. */
      private static final JsonFactory JSON_FACTORY = new JacksonFactory() ;
  
      /** instance of the HTTP transport. */
      private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport() ;
  
      /** Global instance of the Google Drive - the first connect will initialize */
      private static Drive drive;
  
      /*
       * instance variables
       */
      private String accessToken ;
  
      public static void main(String[] args) throws GeneralSecurityException, IOException {
  
          String CLIENTID = "XXXXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@developer.gserviceaccount.com" ;
          String CLIENTUSER = "XXXXXXXX@gmail.com" ;
          String P2FILE = "random/src/main/resources/test.p12" ;
  
          try {
              GoogleCredential credential = new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT)
                      .setJsonFactory(JSON_FACTORY)
                      .setServiceAccountId(CLIENTID)
                      .setServiceAccountScopes(Collections.singleton(DriveScopes.DRIVE_FILE))
                      .setServiceAccountPrivateKeyFromP12File(new java.io.File(P2FILE))
                      .setServiceAccountUser(CLIENTUSER)
                      .addRefreshListener(new CredentialRefreshListener() {
                          @Override
                          public void onTokenResponse(
                                  Credential credential,
                                  TokenResponse tokenResponse) throws IOException {
  
                              String token = tokenResponse.getAccessToken();
                              System.out.println("GOOGLEDRIVE token refreshed " + tokenResponse.getTokenType() + " successfully");
                          }
  
                          @Override
                          public void onTokenErrorResponse(
                                  Credential credential,
                                  TokenErrorResponse tokenErrorResponse) throws IOException {
  
                              System.out.println("GOOGLEDRIVE token refresh failure : " + tokenErrorResponse);
                          }
                      })
                      .build();
  
              /*
               * set up the global Drive instance
               */
              drive = new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential).setApplicationName("API Project").build();
  
              /*
               * output results
               */
              Drive.Files.List fileRequest = drive.files().list() ;
              FileList afiles = fileRequest.execute() ;
              List&lt;File&gt; bFiles = afiles.getItems() ;
              for(File file : bFiles) {
                  System.out.println(file.getTitle()) ;
               }
          }
          catch (GeneralSecurityException | IOException e) {
              e.printStackTrace();
          }
  
      }
  
  }
  </code></pre>
  
  <p>But the output I see is this :</p>
  
  <pre><code>GOOGLEDRIVE token refresh failure : null
  com.google.api.client.auth.oauth2.TokenResponseException: 401 Unauthorized
      at com.google.api.client.auth.oauth2.TokenResponseException.from(TokenResponseException.java:105)
      at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:287)
      at com.google.api.client.auth.oauth2.TokenRequest.execute(TokenRequest.java:307)
      at com.google.api.client.googleapis.auth.oauth2.GoogleCredential.executeRefreshToken(GoogleCredential.java:384)
      at com.google.api.client.auth.oauth2.Credential.refreshToken(Credential.java:489)
      at com.google.api.client.auth.oauth2.Credential.intercept(Credential.java:217)
      at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:859)
      at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
      at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
      at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
      at GoogleDriveTest.main(GoogleDriveTest.java:81)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:483)
      at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
  
  Process finished with exit code 0
  </code></pre>
  
  <p>Can anyone provide some pointers on Service Account access to Google Drive and what I might be doing wrong here ?</p>
  
  <p>As the Service Account is created under my Google Account (XXXXXXXX@gmail.com) I assumed it would have access to the Drive once the API was enabled.</p>
  
  <p>I have seen other posts about granting access to Service Accounts to a domain account via an admin console - but my account is a plain / standard google account. I'm not even sure what a domain account is !</p>
  
  <p>All help would be greatly appreciated.</p>