通过 Java 使用 Admin SDK 执行组操作
Executing Group Operations with the Admin SDK via Java
我有一个与 Google Apps for Work 域集成的应用程序,需要从 oauth 1 迁移到 oauth 2。
这是一个服务器应用程序,只需要:
- 列出域中的所有组。
- 列出指定组中的用户。
- 将成员添加到指定组。
- 从指定组中删除成员。
鉴于以上情况,我认为这应该使用服务帐户来完成。我创建了这个,下载了 P12 令牌(P12 和 JSON 令牌有什么区别?)并通过开发者控制台启用了 Admin SDK API。 API 在域的控制面板中启用了访问权限,并且我已经为与服务帐户关联的客户端 ID 启用了范围 https://www.googleapis.com/auth/admin.directory.group.member。
我尝试了一些围绕组的随机操作,但得到了 "insufficient permissions" 响应。
{
"code" : 403,
"errors" : [ {
"domain" : "global",
"message" : "Insufficient Permission",
"reason" : "insufficientPermissions"
} ],
"message" : "Insufficient Permission"
}
无论如何,首先,我正在寻找正确实现上述操作所需的代码方面的帮助,然后查看是否仍然存在权限问题:
import java.io.File;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Collections;
import org.apache.commons.httpclient.HttpException;
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.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.model.Group;
import com.google.api.services.admin.directory.model.Groups;
import com.google.api.services.admin.directory.model.Users;
public class GoogleAppsService {
HttpTransport httpTransport;
JsonFactory jsonFactory;
public GoogleAppsService() throws GeneralSecurityException, IOException {
httpTransport = GoogleNetHttpTransport.newTrustedTransport();
jsonFactory = JacksonFactory.getDefaultInstance();
}
public GoogleCredential getCredentials() throws HttpException, IOException, GeneralSecurityException {
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId("179997031769-pf4t5hifo7dmtbqul1dbl9rulneijl7o@developer.gserviceaccount.com")
.setServiceAccountScopes(Collections.singleton("https://www.googleapis.com/auth/admin.directory.group.member"))
.setServiceAccountPrivateKeyFromP12File(
new File(this.getClass().getResource("/google_apps/google-apps-key.p12").getPath())).build();
return credential;
}
public void listGroups() throws Exception{
GoogleCredential credentials = getCredentials();
Directory directory = new Directory.Builder(
httpTransport, jsonFactory, credentials)
.setApplicationName("xyz")
.build();
//403 insufficient permissions thrown below is the above correct??
Groups result = directory.groups().list().execute();
System.out.println(result);
//iterate and print id/alias of each group
}
public void listUsers(String groupName) throws Exception {
GoogleCredential credentials = getCredentials();
//iterate and print email of each member for specified group
}
public void addUser(String groupname, String emailAddress)throws Exception {
GoogleCredential credentials = getCredentials();
}
public void removeUser(String groupName, String emailAddress)throws Exception {
GoogleCredential credentials = getCredentials();
}
public static void main(String[] args) throws Exception {
try {
GoogleAppsService service = new GoogleAppsService();
service.listGroups();
} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
好的,终于可以使用下面的完整解决方案了。关键是指定服务帐户用户(Google Apps 帐户上管理员用户的电子邮件地址)并在获取组列表时调用 setCustomer("my_customer")。
public class GoogleAppsService {
private static final Logger LOGGER = Logger.getLogger(GoogleAppsService.class);
private static final String SERVICE_ACCOUNT_ID = "SERVICE_ACCOUNT_KEY";
private static final String SERVICE_ACCOUNT_USER = "EMAIL_ADDRESS_OF_ADMIN_ACCOUNT_ON_GOOGLE_APPS";
private static final String APPLICATION_NAME = "APP_NAME";
private HttpTransport httpTransport;
private JsonFactory jsonFactory;
private String googleAppsAllEmailListName;
private String googleAppsCommitteeEmailListName;
public GoogleAppsService() throws GeneralSecurityException, IOException {
httpTransport = GoogleNetHttpTransport.newTrustedTransport();
jsonFactory = JacksonFactory.getDefaultInstance();
}
protected Directory getDirectory() throws HttpException, IOException, GeneralSecurityException {
InputStream in = this.getClass().getResourceAsStream("/google_apps/google-apps-key.p12");
PrivateKey privateKey = SecurityUtils.loadPrivateKeyFromKeyStore(SecurityUtils.getPkcs12KeyStore(), in, "notasecret",
"privatekey", "notasecret");
GoogleCredential credentials = new GoogleCredential.Builder().setTransport(httpTransport).setJsonFactory(jsonFactory)
.setServiceAccountId(SERVICE_ACCOUNT_ID)
.setServiceAccountScopes(Arrays.asList(DirectoryScopes.ADMIN_DIRECTORY_GROUP))
.setServiceAccountUser(SERVICE_ACCOUNT_USER).setServiceAccountPrivateKey(privateKey).build();
Directory directory = new Directory.Builder(httpTransport, jsonFactory, credentials).setApplicationName(APPLICATION_NAME)
.build();
return directory;
}
protected Groups listGroups(Directory directory) throws Exception {
//IF SPECIFYING THE SERVICE_ACCOUNT_USER WHEN CONNECTING YOU CAN USE setCustomer("my_customer")
return directory.groups().list().setCustomer("my_customer").execute();
}
protected Group getGroup(Directory directory, String emailAddress) throws IOException {
Group group = directory.groups().get(emailAddress).execute();
LOGGER.debug("Returning Group: " + group != null ? group.getEmail() + "(" + group.getDirectMembersCount() + " members)"
: "! no group loaded");
return group;
}
protected Members listGroupMembers(Directory directory, Group group) throws Exception {
return directory.members().list(group.getEmail()).execute();
}
protected boolean isMemberInGroup(Directory directory, Group group, String emailAddress) throws IOException {
boolean exists = false;
Members memberList = directory.members().list(group.getEmail()).execute();
List<Member> members = memberList.getMembers();
if (members != null) {
for (Member member : members) {
if (member.getEmail().equals(emailAddress)) {
exists = true;
break;
}
}
}
return exists;
}
protected void addMemberToGroup(Directory directory, Group group, String emailAddress) throws Exception {
Member member = new Member();
member.setEmail(emailAddress);
LOGGER.debug("Attempting Insert of Member to Group: " + group != null ? group.getEmail() : "! no group loaded");
directory.members().insert(group.getEmail(), member).execute();
}
protected void removeMemberFromGroup(Directory directory, Group group, String emailAddress) throws Exception {
LOGGER.debug("Attempting Deletetion of Member to Group: " + group != null ? group.getEmail() : "! no group loaded");
directory.members().delete(group.getEmail(), emailAddress).execute();
}
public void addMemberToMembersList(String emailAddress) throws MailingListException {
addMemberToList(googleAppsAllEmailListName, emailAddress);
}
public void addMemberToCommitteeList(String emailAddress) throws MailingListException {
addMemberToList(googleAppsCommitteeEmailListName, emailAddress);
}
protected void addMemberToList(String listAddress, String emailAddress) throws MailingListException {
try {
Directory directory = getDirectory();
Group group = getGroup(directory, listAddress);
if (!isMemberInGroup(directory, group, emailAddress)) {
addMemberToGroup(directory, group, emailAddress);
}
} catch (Exception e) {
LOGGER.error("Error adding member (" + emailAddress + ") to mailing list " + listAddress, e);
throw new MailingListException(e);
}
}
public void removeMemberFromMembersList(String emailAddress) throws MailingListException {
removeMemberFromList(googleAppsAllEmailListName, emailAddress);
}
public void removeMemberFromCommitteeList(String emailAddress) throws MailingListException {
removeMemberFromList(googleAppsCommitteeEmailListName, emailAddress);
}
protected void removeMemberFromList(String listAddress, String emailAddress) throws MailingListException {
try {
Directory directory = getDirectory();
Group group = getGroup(directory, listAddress);
if (isMemberInGroup(directory, group, emailAddress)) {
removeMemberFromGroup(directory, group, emailAddress);
}
} catch (Exception e) {
LOGGER.error("Error removing member (" + emailAddress + ") from mailing list " + listAddress, e);
throw new MailingListException(e);
}
}
public void setHttpTransport(HttpTransport httpTransport) {
this.httpTransport = httpTransport;
}
public void setJsonFactory(JsonFactory jsonFactory) {
this.jsonFactory = jsonFactory;
}
public void setGoogleAppsAllEmailListName(String googleAppsAllEmailListName) {
this.googleAppsAllEmailListName = googleAppsAllEmailListName;
}
public void setGoogleAppsCommitteeEmailListName(String googleAppsCommitteeEmailListName) {
this.googleAppsCommitteeEmailListName = googleAppsCommitteeEmailListName;
}
}
我有一个与 Google Apps for Work 域集成的应用程序,需要从 oauth 1 迁移到 oauth 2。
这是一个服务器应用程序,只需要:
- 列出域中的所有组。
- 列出指定组中的用户。
- 将成员添加到指定组。
- 从指定组中删除成员。
鉴于以上情况,我认为这应该使用服务帐户来完成。我创建了这个,下载了 P12 令牌(P12 和 JSON 令牌有什么区别?)并通过开发者控制台启用了 Admin SDK API。 API 在域的控制面板中启用了访问权限,并且我已经为与服务帐户关联的客户端 ID 启用了范围 https://www.googleapis.com/auth/admin.directory.group.member。
我尝试了一些围绕组的随机操作,但得到了 "insufficient permissions" 响应。
{
"code" : 403,
"errors" : [ {
"domain" : "global",
"message" : "Insufficient Permission",
"reason" : "insufficientPermissions"
} ],
"message" : "Insufficient Permission"
}
无论如何,首先,我正在寻找正确实现上述操作所需的代码方面的帮助,然后查看是否仍然存在权限问题:
import java.io.File;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Collections;
import org.apache.commons.httpclient.HttpException;
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.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.model.Group;
import com.google.api.services.admin.directory.model.Groups;
import com.google.api.services.admin.directory.model.Users;
public class GoogleAppsService {
HttpTransport httpTransport;
JsonFactory jsonFactory;
public GoogleAppsService() throws GeneralSecurityException, IOException {
httpTransport = GoogleNetHttpTransport.newTrustedTransport();
jsonFactory = JacksonFactory.getDefaultInstance();
}
public GoogleCredential getCredentials() throws HttpException, IOException, GeneralSecurityException {
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId("179997031769-pf4t5hifo7dmtbqul1dbl9rulneijl7o@developer.gserviceaccount.com")
.setServiceAccountScopes(Collections.singleton("https://www.googleapis.com/auth/admin.directory.group.member"))
.setServiceAccountPrivateKeyFromP12File(
new File(this.getClass().getResource("/google_apps/google-apps-key.p12").getPath())).build();
return credential;
}
public void listGroups() throws Exception{
GoogleCredential credentials = getCredentials();
Directory directory = new Directory.Builder(
httpTransport, jsonFactory, credentials)
.setApplicationName("xyz")
.build();
//403 insufficient permissions thrown below is the above correct??
Groups result = directory.groups().list().execute();
System.out.println(result);
//iterate and print id/alias of each group
}
public void listUsers(String groupName) throws Exception {
GoogleCredential credentials = getCredentials();
//iterate and print email of each member for specified group
}
public void addUser(String groupname, String emailAddress)throws Exception {
GoogleCredential credentials = getCredentials();
}
public void removeUser(String groupName, String emailAddress)throws Exception {
GoogleCredential credentials = getCredentials();
}
public static void main(String[] args) throws Exception {
try {
GoogleAppsService service = new GoogleAppsService();
service.listGroups();
} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
好的,终于可以使用下面的完整解决方案了。关键是指定服务帐户用户(Google Apps 帐户上管理员用户的电子邮件地址)并在获取组列表时调用 setCustomer("my_customer")。
public class GoogleAppsService {
private static final Logger LOGGER = Logger.getLogger(GoogleAppsService.class);
private static final String SERVICE_ACCOUNT_ID = "SERVICE_ACCOUNT_KEY";
private static final String SERVICE_ACCOUNT_USER = "EMAIL_ADDRESS_OF_ADMIN_ACCOUNT_ON_GOOGLE_APPS";
private static final String APPLICATION_NAME = "APP_NAME";
private HttpTransport httpTransport;
private JsonFactory jsonFactory;
private String googleAppsAllEmailListName;
private String googleAppsCommitteeEmailListName;
public GoogleAppsService() throws GeneralSecurityException, IOException {
httpTransport = GoogleNetHttpTransport.newTrustedTransport();
jsonFactory = JacksonFactory.getDefaultInstance();
}
protected Directory getDirectory() throws HttpException, IOException, GeneralSecurityException {
InputStream in = this.getClass().getResourceAsStream("/google_apps/google-apps-key.p12");
PrivateKey privateKey = SecurityUtils.loadPrivateKeyFromKeyStore(SecurityUtils.getPkcs12KeyStore(), in, "notasecret",
"privatekey", "notasecret");
GoogleCredential credentials = new GoogleCredential.Builder().setTransport(httpTransport).setJsonFactory(jsonFactory)
.setServiceAccountId(SERVICE_ACCOUNT_ID)
.setServiceAccountScopes(Arrays.asList(DirectoryScopes.ADMIN_DIRECTORY_GROUP))
.setServiceAccountUser(SERVICE_ACCOUNT_USER).setServiceAccountPrivateKey(privateKey).build();
Directory directory = new Directory.Builder(httpTransport, jsonFactory, credentials).setApplicationName(APPLICATION_NAME)
.build();
return directory;
}
protected Groups listGroups(Directory directory) throws Exception {
//IF SPECIFYING THE SERVICE_ACCOUNT_USER WHEN CONNECTING YOU CAN USE setCustomer("my_customer")
return directory.groups().list().setCustomer("my_customer").execute();
}
protected Group getGroup(Directory directory, String emailAddress) throws IOException {
Group group = directory.groups().get(emailAddress).execute();
LOGGER.debug("Returning Group: " + group != null ? group.getEmail() + "(" + group.getDirectMembersCount() + " members)"
: "! no group loaded");
return group;
}
protected Members listGroupMembers(Directory directory, Group group) throws Exception {
return directory.members().list(group.getEmail()).execute();
}
protected boolean isMemberInGroup(Directory directory, Group group, String emailAddress) throws IOException {
boolean exists = false;
Members memberList = directory.members().list(group.getEmail()).execute();
List<Member> members = memberList.getMembers();
if (members != null) {
for (Member member : members) {
if (member.getEmail().equals(emailAddress)) {
exists = true;
break;
}
}
}
return exists;
}
protected void addMemberToGroup(Directory directory, Group group, String emailAddress) throws Exception {
Member member = new Member();
member.setEmail(emailAddress);
LOGGER.debug("Attempting Insert of Member to Group: " + group != null ? group.getEmail() : "! no group loaded");
directory.members().insert(group.getEmail(), member).execute();
}
protected void removeMemberFromGroup(Directory directory, Group group, String emailAddress) throws Exception {
LOGGER.debug("Attempting Deletetion of Member to Group: " + group != null ? group.getEmail() : "! no group loaded");
directory.members().delete(group.getEmail(), emailAddress).execute();
}
public void addMemberToMembersList(String emailAddress) throws MailingListException {
addMemberToList(googleAppsAllEmailListName, emailAddress);
}
public void addMemberToCommitteeList(String emailAddress) throws MailingListException {
addMemberToList(googleAppsCommitteeEmailListName, emailAddress);
}
protected void addMemberToList(String listAddress, String emailAddress) throws MailingListException {
try {
Directory directory = getDirectory();
Group group = getGroup(directory, listAddress);
if (!isMemberInGroup(directory, group, emailAddress)) {
addMemberToGroup(directory, group, emailAddress);
}
} catch (Exception e) {
LOGGER.error("Error adding member (" + emailAddress + ") to mailing list " + listAddress, e);
throw new MailingListException(e);
}
}
public void removeMemberFromMembersList(String emailAddress) throws MailingListException {
removeMemberFromList(googleAppsAllEmailListName, emailAddress);
}
public void removeMemberFromCommitteeList(String emailAddress) throws MailingListException {
removeMemberFromList(googleAppsCommitteeEmailListName, emailAddress);
}
protected void removeMemberFromList(String listAddress, String emailAddress) throws MailingListException {
try {
Directory directory = getDirectory();
Group group = getGroup(directory, listAddress);
if (isMemberInGroup(directory, group, emailAddress)) {
removeMemberFromGroup(directory, group, emailAddress);
}
} catch (Exception e) {
LOGGER.error("Error removing member (" + emailAddress + ") from mailing list " + listAddress, e);
throw new MailingListException(e);
}
}
public void setHttpTransport(HttpTransport httpTransport) {
this.httpTransport = httpTransport;
}
public void setJsonFactory(JsonFactory jsonFactory) {
this.jsonFactory = jsonFactory;
}
public void setGoogleAppsAllEmailListName(String googleAppsAllEmailListName) {
this.googleAppsAllEmailListName = googleAppsAllEmailListName;
}
public void setGoogleAppsCommitteeEmailListName(String googleAppsCommitteeEmailListName) {
this.googleAppsCommitteeEmailListName = googleAppsCommitteeEmailListName;
}
}