0
votes

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.

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:

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?

1
A small update. When attempting to obtain Chrome devices, I added this code: ChromeOsDevices chromedevices = dir.chromeosdevices().list("myCustomerId").execute(); Naturally, I initially received a 403. I had to add both the SCOPES for the service account in the Java code and the Security API access AND the "Services Admin" role for the person I am impersonating. I believe I've tried various combinations, and the request was not successful until both SCOPE and ROLEs were set appropriately.Jerry Thome

1 Answers

0
votes

Service accounts are not in the G Suite domain (even if they are owned by a user / project in it) and thus cannot be granted admin access to the G Suite domain. All they can do is impersonate users in the domain with Domain-Wide Delegation.

What you likely want to settle on is granting regular OAuth as an admin user using a client ID and secret and being sure to get a long-lived refresh token access_type=offline. This will allow you to refresh the access token whenever it expires and continue acting as the single admin user as long as they don't revoke your access.