I am having problems authenticating to Google Calendar API v3 using the Java client library (google-api-client version 1.13.2-beta, google-api-services-calendar version v3-rev26-1.13.2-beta).
We have a marketplace app, and installing that app should give it the required credentials for reading (and writing) Google Calendar events.
We are using 2-legged OAuth 1.0, with Hmac, meaning no tokens are necessary. This is just what I am trying to do, but with Calendar instead of Tasks: https://developers.google.com/google-apps/help/articles/2lo-in-tasks-for-marketplace
This is the error I'm getting from Google:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized
{
"code" : 401,
"errors" : [ {
"domain" : "global",
"location" : "Authorization",
"locationType" : "header",
"message" : "Invalid Credentials",
"reason" : "authError"
} ],
"message" : "Invalid Credentials"
}
We also have customers that don't use the Marketplace app, but have given our domain the appropriate permissions by hand, and everything works fine for them. It is only the customers with the Marketplace app that have this problem (using a different consumerKey and consumerSecret), and that leads me to believe that there is nothing wrong with the code, but we overlooked something somewhere in the Google setup..
The permissions for the Marketplace app look fine.
I have followed every guide I could find, appropriate for our setup (not plenty of them out there though), and as far as I can see I'm doing the right thing.
The API key seems correctly set up (access to the Calendar API is granted). As I mentioned, this works for our customers not coming from the Marketplace app, and they are using the same API key.
Anyway, here's a failing JUnit test to reproduce the error:
import java.io.IOException;
import java.util.List;
import org.junit.Test;
import com.google.api.client.auth.oauth.OAuthHmacSigner;
import com.google.api.client.auth.oauth.OAuthParameters;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.api.services.calendar.Calendar;
import com.google.api.services.calendar.CalendarRequest;
import com.google.api.services.calendar.CalendarRequestInitializer;
import com.google.api.services.calendar.model.CalendarListEntry;
import junit.framework.Assert;
public class GoogleOAuthTest {
@Test
public void test() {
final String API_KEY = "...";
final String CONSUMER_KEY = "...";
final String CONSUMER_KEY_SECRET = "...";
final String GOOGLE_USER = "[email protected]";
// The 2-LO authorization section
OAuthHmacSigner signer = new OAuthHmacSigner();
signer.clientSharedSecret = CONSUMER_KEY_SECRET;
final OAuthParameters oauthParameters = new OAuthParameters();
oauthParameters.version = "1";
oauthParameters.consumerKey = CONSUMER_KEY;
oauthParameters.signer = signer;
Calendar service = new Calendar.Builder(new NetHttpTransport(), new JacksonFactory(), oauthParameters)
.setApplicationName("myapp")
.setCalendarRequestInitializer(new CalendarRequestInitializer() {
@Override
protected void initializeCalendarRequest(CalendarRequest<?> request) throws IOException {
request.setKey(API_KEY);
}
}).build();
try {
com.google.api.services.calendar.Calendar.CalendarList.List list = service.calendarList().list();
list.getUnknownKeys().put("xoauth_requestor_id", GOOGLE_USER);
// This is where I get the exception!
List<CalendarListEntry> calendarList = list.execute().getItems();
} catch (IOException e) {
Assert.fail("Test failed: " + e.getMessage());
}
}
}
What could I be doing wrong? Is there something obviously wrong with my code, or is there something we might have missed in the Google setup?