0

I am trying to connect to the google Contacts api to access my contacts/people that are saved in google but it throws a TokenResponseException:401 Unauthorized. I am somehow new to Google Oauth2.0. I already downloaded the Service Account Key File to my project root directory as required.

Below is the code:

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.gdata.client.contacts.ContactsService;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Arrays;

public class Connector {
private static ContactsService contactService = null;
    private static HttpTransport httpTransport;

    private static final String APPLICATION_NAME = "example";
    private static final String SERVICE_ACCOUNT_EMAIL = "example_mail@example-166608.iam.gserviceaccount.com";
    private static final java.util.List<String> SCOPE = Arrays.asList("https://www.google.com/m8/feeds/");

    private Connector() {
        // explicit private no-args constructor
    }

    public static void main(String[] args) {
        System.out.println(getInstance());
    }

    public static ContactsService getInstance() {
        if (contactService == null) {
            try {
                contactService = connect();
            } catch (GeneralSecurityException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return contactService;
    }

    private static ContactsService connect() throws GeneralSecurityException, IOException {
        httpTransport = GoogleNetHttpTransport.newTrustedTransport();

        java.io.File p12File = new java.io.File("example-e8135faedf4e.p12");

        // @formatter:off
        GoogleCredential credential = new GoogleCredential.Builder()
                .setTransport(httpTransport)
                .setJsonFactory(JacksonFactory.getDefaultInstance())
                .setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
                .setServiceAccountScopes(SCOPE)
                .setServiceAccountPrivateKeyFromP12File(p12File)
                .setServiceAccountUser("example@gmail.com")
                .build();
        // @formatter:on

        if (!credential.refreshToken()) {
            throw new RuntimeException("Failed OAuth to refresh the token");
        }

        ContactsService myService = new ContactsService(APPLICATION_NAME);
        myService.setOAuth2Credentials(credential);

        return myService;
    }
}

However the following exception is thrown:

com.google.api.client.auth.oauth2.TokenResponseException: 401 Unauthorized
null
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 Connector.connect(Connector.java:58) at Connector.getInstance(Connector.java:31) at Connector.main(Connector.java:25) BUILD SUCCESSFUL (total time: 9 seconds)

2 Answers2

0

Based from this related thread, TokenResponseException could be caused by many things like invalid client ID, client secret or scopes and by refresh token overuse. It is also stated here that another possible source for a "401 Unauthorized" exception is leaving the credential.refreshToken() away. The call is necessary to write the access-code into the reference.

Additional reference which might also help: 401 response when athenticating via Service Account and OAuth2 to GoogleDrive

abielita
  • 13,147
  • 2
  • 17
  • 59
0

I see that your code is pretty much what is in the Quickstart samples. If this worked at least once, check if you have any token saved under tokens folder.