I'm trying to use googleapi 2.0 with service account to use Directory gooogle admin sdk on user on an entrprise domain. I've proceeded as suggested (this for instance) and prepared a "wish to work" poc java code.
Somthing like this...
package com.mc3info.google.api20.test;
import java.io.File;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.admin.directory.Directory;
import com.google.api.services.admin.directory.Directory.Members;
import com.google.api.services.admin.directory.Directory.Users.Get;
import com.google.api.services.admin.directory.DirectoryScopes;
import com.google.api.services.admin.directory.Directory.Groups;
import com.google.api.services.admin.directory.Directory.Users;
import com.google.api.services.admin.directory.model.User;
public class TestUsersList {
public static void main(String[] args) {
try {
File f = new File("config/xxxxxxx-privatekey.p12");
System.out.println(f.getAbsolutePath());
ArrayList<String> scopes = new ArrayList<String>();
// scopes.add(DirectoryScopes.ADMIN_DIRECTORY_GROUP);
// scopes.add(DirectoryScopes.ADMIN_DIRECTORY_GROUP_READONLY );
// scopes.add(DirectoryScopes.ADMIN_DIRECTORY_GROUP_MEMBER);
// scopes.add(DirectoryScopes.ADMIN_DIRECTORY_GROUP_MEMBER_READONLY);
scopes.add(DirectoryScopes.ADMIN_DIRECTORY_USER );
scopes.add(DirectoryScopes.ADMIN_DIRECTORY_USER_READONLY );
// scopes.add(DirectoryScopes.ADMIN_DIRECTORY_USER_SECURITY);
HttpTransport myHttpTransport = new NetHttpTransport();
JsonFactory JSON_FACTORY = new JacksonFactory();
GoogleCredential credential = (new GoogleCredential.Builder()
.setTransport(myHttpTransport )
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId("xxxxxxxxxxxx@developer.gserviceaccount.com")
.setJsonFactory(JSON_FACTORY)
.setServiceAccountPrivateKeyFromP12File(f )
.setServiceAccountScopes(scopes)
).build();
credential.refreshToken();
// String at = credential.getAccessToken();
String applicationName = "NYAPPLICATIONNAME";
Directory dir = new Directory.Builder(myHttpTransport, JSON_FACTORY, credential)
.setApplicationName(applicationName )
.setHttpRequestInitializer(credential)
.build();
com.google.api.services.admin.directory.Directory.Users.List ures = dir.users().list();
ures.setDomain("genericidoc.it");
ures.setOrderBy("email");
// ures.setSortOrder("ASCENDING");
// ures.setFields("users(agreedToTerms,changePasswordAtNextLogin,creationTime,customerId,deletionTime,etag,hashFunction,id,includeInGlobalAddressList,ipWhitelisted,isAdmin,isDelegatedAdmin,isMailboxSetup,kind,lastLoginTime,name,orgUnitPath,password,primaryEmail,suspended,suspensionReason,thumbnailPhotoUrl");
com.google.api.services.admin.directory.model.Users lures = ures.execute();
//HERE print all data
// for (){
// System.out.println("Utente : ");
// }
//
Groups grp = dir.groups();
com.google.api.services.admin.directory.model.Groups res = grp.list().execute();
// Directory.Members.List members = dir.members().list("someexisting email");
/*
* Values for getting GoogleCredential, found in the
* "Service account section" at:
* https://code.google.com/apis/console/#access
*/
// serviceAccountId from the "Email address" field.
// Name of group to get for testing the authentication
} catch (Throwable t) {
t.printStackTrace();
}
}
}
but getting a 403 error:
And ... Yes, refreshToken() invokation should not be requied but it ensures me thath al least handshake was ok...
403 Forbidden
{
"code" : 403,
"errors" : [ {
"domain" : "global",
"message" : "Not Authorized to access this resource/api",
"reason" : "forbidden"
} ],
"message" : "Not Authorized to access this resource/api"
}
Take a look at Google's docs on using service accounts with Admin SDK for domain-wide delegation.
You didn't mention it, but you definitely need to grant the service account's client id access to the Admin SDK scopes from your Google Apps Control Panel.
Your code is missing a line like
.setServiceAccountUser(userEmail)
which allows the service account to impersonate a user in your Google Apps domain who has rights to search the directory (probably a super admin user).