The goal is to establish a Service Account in the G-Suite platform that an application can use to perform actions without prompting users to authenticate.
We are experiencing issues very similar to the following postings, but slightly differently.
- Google Admin SDK authentication with service account
- How to authorise a service account to access the Google Admin API
As long as we follow the 'impersonation" flow, things work. With impersonation, the authorization rules follow the user being impersonated. Ideally, we want to SCOPE the service account accordingly and not impersonate a user. When we do this, we constantly receive a 403.
We've tried our best to follow the instructions here:
- https://developers.google.com/admin-sdk/directory/v1/guides/delegation
- https://developers.google.com/identity/protocols/OAuth2ServiceAccount?hl=en_US#delegatingauthority
- https://medium.com/@Skaaptjop/access-gsuite-apis-on-your-domain-using-a-service-account-e2a8dbda287c
Our Java snippet is similar to this:
final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
File file = new File(MdmResource.class.getClassLoader().getResource("myproject.p12").getFile());
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(HTTP_TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId("105601508644514129999")
.setServiceAccountPrivateKeyFromP12File(file)
.setServiceAccountScopes(
Collections.singletonList(DirectoryScopes.ADMIN_DIRECTORY_USER_READONLY))
.setServiceAccountUser("[email protected]") // 403 when this is commented out
.build();
Directory dir = new Directory(HTTP_TRANSPORT, JSON_FACTORY, credential);
Get result = dir.users().get("[email protected]");
User user = result.execute();
System.out.println(user.get("customerId"));
In GCP, we created the ServiceAccount while logged in as a superadmin. We enabled Domain-Wide delegation and generated the keys (in this example, the p12 type and used the corresponding file as input into the Java app).
Then, in the API Library, we enabled Admin SDK.
In the Google Admin, under Security/Advanced settings, we setup the scopes. We used 105601508644514129999 and https://www.googleapis.com/auth/admin.directory.device.mobile,https://www.googleapis.com/auth/admin.directory.user.readonly,https://www.googleapis.com/auth/admin.directory.user
When we run the Java code, we see the following when "setServiceAccountUser" is commented out (works fine when impersonating, as long as the user has the right permissions):
{
"code" : 403,
"errors" : [ {
"domain" : "global",
"message" : "Not Authorized to access this resource/api",
"reason" : "forbidden"
} ],
"message" : "Not Authorized to access this resource/api"
}
So, it seems like our SA is not correctly connected to scopes, but I'm out of ideas how to do this.
BTW, the 105601508644514129999 is the SA Unique ID and Client ID of the OAuth 2.0 credentials that were automatically generated during the SA creation process. We also used the SA Email for the "setServiceAccountId" as shown in the following example, but still getting 403. https://developers.google.com/admin-sdk/directory/v1/guides/delegation. Actually, I think this example has another issue with .setServiceAccountScopes too.
Finally...
<dependency>
<groupId>com.google.auth</groupId>
<artifactId>google-auth-library-oauth2-http</artifactId>
<version>0.20.0</version>
</dependency>
<!-- Used to navigate Google Directory services, like https://developers.google.com/admin-sdk/directory -->
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-admin-directory</artifactId>
<version>directory_v1-rev117-1.25.0</version>
</dependency>
Any thoughts?