(I've reviewed similar questions on SO, however none of the suggestions have worked for me)
I have an API service that runs on Google App Engine (on the Google Cloud Platform). I need to authenticate to the Google Admin Directory API so that I can create groups on our GSuite domain.
I initially tried implicit authorisation by following the guide to Obtaining and providing service account credentials manually, but I think that may be limited to communication between apps that are running on Google App Engine. My understanding is that talking to a Google API outside of App Engine requires OAuth 2.0, so I've set things up as follows:
I've set up the App Engine default service account, and I've granted domain wide delegation to the account from within the Google Cloud Platform. I've also delegated domain-wide authority from the GSuite side, by following this guide - https://developers.google.com/admin-sdk/reports/v1/guides/delegation#delegate_domain-wide_authority_to_your_service_account
I've generated a P12 key for the service account. I'm then setting up credentials and using them to instantiate a Google Admin Directory client API as follows:
final List<String> SCOPES = Collections.singletonList(DirectoryScopes.ADMIN_DIRECTORY_GROUP);
final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
/** Email of the Service Account */
final String SERVICE_ACCOUNT_EMAIL = "[email protected]";
final String USER_EMAIL = "[email protected]";
/** Path to the Service Account's Private Key file */
final String SERVICE_ACCOUNT_PKCS12_FILE = "myPath.p12";
String p12Password = "notasecret";
ClassLoader classLoader = this.getClass().getClassLoader();
KeyStore keystore = KeyStore.getInstance("PKCS12");
InputStream keyFileStream = classLoader.getResourceAsStream(SERVICE_ACCOUNT_PKCS12_FILE);
if (keyFileStream == null){
throw new Exception("Key File Not Found.");
}
keystore.load(keyFileStream, p12Password.toCharArray());
PrivateKey pk = (PrivateKey)keystore.getKey("privatekey", p12Password.toCharArray());
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(HTTP_TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
.setServiceAccountScopes(SCOPES)
.setServiceAccountUser(USER_EMAIL)
.setServiceAccountPrivateKey(pk)
.build();
Directory directory = new Directory.Builder(HTTP_TRANSPORT, JSON_FACTORY, null)
.setHttpRequestInitializer(credential).build();
com.google.api.services.admin.directory.model.Group group = new Group();
group.setEmail("[email protected]");
group.setName("test_group");
group.setDescription("test_group_desc");
Group googleGroup = directory.groups().insert(group).execute();
// error on the line above (403: Not Authorized to access this resource/api - forbidden)
I get an error on the final line, where I try to create a new group:
Group googleGroup = directory.groups().insert(group).execute();
403: Not Authorized to access this resource/api - forbidden
What do I need to do to successfully authenticate?