mamata nayak
mamata nayak

Reputation: 21

Google Admin API - Service Account withJSON - 403 Forbidden error

I am trying make the google admin api call for users using service account and JSON Key file from java code.

  1. The service account has domain-wide delegation enabled .
  2. the client id is authorized for scope - https://www.googleapis.com/auth/admin.directory.user

Still I am getting the error :

Unknown Exception : com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
PUT https://www.googleapis.com/admin/directory/v1/users/[email protected]
{
  "code" : 403,
  "errors" : [ {
    "domain" : "global",
    "message" : "Not Authorized to access this resource/api",
    "reason" : "forbidden"
  } ],
  "message" : "Not Authorized to access this resource/api"
}

I have been trying this from some time now..Please help here Here is the code -

GoogleCredentials credentials;
try (FileInputStream serviceAccountStream = new FileInputStream(CREDENTIALS_FILE_PATH)) {
 credentials = ServiceAccountCredentials.fromStream(serviceAccountStream);
}

List < String > scopes = new ArrayList < String > ();
scopes.add("https://www.googleapis.com/auth/admin.directory.user");

credentials = credentials.createScoped(scopes);

// Build a new authorized API client service.
//final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
/*Directory service = new Directory.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
        .setApplicationName(APPLICATION_NAME)
        .build();*/
HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credentials);

/*Directory service = new Directory.Builder(HTTP_TRANSPORT, JSON_FACTORY, credentials)
        .setApplicationName(APPLICATION_NAME)
        .build();*/
Directory service = new Directory.Builder(new NetHttpTransport(), JacksonFactory.getDefaultInstance(), requestInitializer).setApplicationName "APPLICATION_NAME").build();

User user = new User();
user.setSuspended(true);
user.setSuspensionReason("Worker on Leave");
Directory.Users.Update result = null;
result = service.users().update(workerEmailId, user);
user = result.execute();

if (user == null || user.size() == 0) {
 System.out.println("No user updated.");
} else {
 System.out.println("User:");
 System.out.println(user.getName().getFullName());
 System.out.println("User Status for Suspension :");
 System.out.println(user.getSuspended());
}
}

Upvotes: 2

Views: 1756

Answers (1)

ziganotschka
ziganotschka

Reputation: 26836

  • The Directory API can only be used by admins
  • A Service account is not an admin
  • If the service account shall act on behalf on the admin, you need to

    • enable G Suite Domain-wide Delegation (as you already did)
    • impersonate the service account as the admin by setting the user to be impersonated

    • In java you need to build a GoogleCredential specifying ServiceAccountId, PrivateKey and ServiceAccountUser.

Sample from the documentation:

GoogleCredential credential = new GoogleCredential.Builder()
    .setTransport(httpTransport)
    .setJsonFactory(JSON_FACTORY)
    .setServiceAccountId(emailAddress)
    .setServiceAccountPrivateKeyFromP12File(new File("MyProject.p12"))
    .setServiceAccountScopes(Collections.singleton(YOUR SCOPE))
    .setServiceAccountUser("EMAIL OF THE ADMIN")
    .build();

Upvotes: 4

Related Questions