4

I need to read the list of users (and groups) from my google domain.

So I went to my Google APIs Console and enabled Admin SDK and created a Service Account to call Google APIs. I use the following google libraries

  • google-api-services-admin-directory_v1-rev11-1.16.0-rc.jar
  • google-api-client-1.16.0-rc.jar

My code is

     /*
     * Global instance of the JSON factory.
     */
    final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
     /*
      Global instance of the HTTP transport.
     */
        HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();

        Collection<String> scopeList = new ArrayList<>();
        scopeList.add(DirectoryScopes.ADMIN_DIRECTORY_USER);
        scopeList.add(DirectoryScopes.ADMIN_DIRECTORY_GROUP);
        scopeList.add(DirectoryScopes.ADMIN_DIRECTORY_GROUP_MEMBER);

        GoogleCredential credential = new GoogleCredential.Builder()
                .setTransport(httpTransport)
                .setJsonFactory(JSON_FACTORY)
                .setServiceAccountId("nnnnnn@developer.gserviceaccount.com")
                .setServiceAccountScopes(scopeList)
                .setServiceAccountPrivateKeyFromP12File(new File("/Path/To/KeyFile/nnnnn-privatekey.p12"))
//                .setServiceAccountUser("admin@mydomain.org")
                .build();

        Directory admin = new Directory.Builder(httpTransport, JSON_FACTORY, credential)
                .setApplicationName("Test")
                .setHttpRequestInitializer(credential).build();


        Users users = admin.users().list().setDomain("mydomain.org").execute();

And I receive this on the last line

Error

{
  "code" : 403,
  "errors" : [ {
    "domain" : "global",
    "message" : "Not Authorized to access this resource/api",
    "reason" : "forbidden"
  } ],
  "message" : "Not Authorized to access this resource/api"
}
    at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:145)
    at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
    at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:312)
    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1045)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:410)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:460)

If I uncomment the commented line (.setServiceAccountUser("admin@mydomain.org")) then I get a different error

    Exception in thread "main" com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request
{
  "error" : "access_denied"
}
    at com.google.api.client.auth.oauth2.TokenResponseException.from(TokenResponseException.java:105)
    at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:287)
    at com.google.api.client.auth.oauth2.TokenRequest.execute(TokenRequest.java:307)
    at com.google.api.client.googleapis.auth.oauth2.GoogleCredential.executeRefreshToken(GoogleCredential.java:269)
    at com.google.api.client.auth.oauth2.Credential.refreshToken(Credential.java:489)
    at com.google.api.client.auth.oauth2.Credential.intercept(Credential.java:217)
    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:858)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:410)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:460)

My account (admin@mydomain.org) is a super administrator. I suspect the Service Account needs to be granted access for the users API scope. But I can not find where I can grant this access. I have a classic UI mode of my Google CPanel. And I don't have "Manage client API access" page in the Advanced tools.

Advanced tools

Also I'm not sure what I should use as an Application Name at .setApplicationName("Test").

Thanks for any help

4

4 回答 4

2

您可以转到管理控制台中的“安全”设置(admin.google.com/AdminHome?chromeless=1&pli=1#SecuritySettings:);然后单击高级设置 > 管理第三方 OAuth 客户端访问。在此映射您的客户端 ID(从 oath2 的 API 访问下的 appconsole code.google.com/apis/console 生成)和“一个或多个 API 范围”之后。使用那里提到的逗号分隔范围。对于 google 目录,您可以使用https://www.googleapis.com/auth/admin.directory.group、https://www.googleapis.com/auth/admin.directory.user

希望在此之后它可以工作:)

于 2013-09-05T10:53:35.650 回答
2

我遇到了完全相同的问题,并被困在这个样本上

对我有什么帮助:1/我没有按照 Jay Lee 的建议将域范围的权限委托给您的服务帐户。但在那之后,我仍然遇到了问题。2/ 然后,根据这篇文章,对 setServiceAccountUser(yourAdminAccount@yourDomain.com) 的调用是强制性的。

于 2014-09-29T16:11:24.417 回答
2

Google Directory API 适用于 Compute Engine 默认服务帐户,您无需在域范围内设置 Google Drive。唯一的事情:您必须设置 serviceAccountUser,这在基于 JSON 的凭据中不受支持。这样你就可以

  • 使用 P12 键
  • 具有解决方法的用户 JSON 凭据:

制作凭证副本:

import static com.google.api.client.googleapis.util.Utils.getDefaultJsonFactory;
import static com.google.api.client.googleapis.util.Utils.getDefaultTransport;

private static final String APPLICATION_NAME = "AnyAppName";

private final List<String> SCOPES = ImmutableList.of(
        DirectoryScopes.ADMIN_DIRECTORY_GROUP_MEMBER, DirectoryScopes.ADMIN_DIRECTORY_USER, DirectoryScopes.ADMIN_DIRECTORY_GROUP);

private Directory service;

@PostConstruct
void init() throws GeneralSecurityException, IOException {
    GoogleCredential credential;
    try (InputStream is = new FileInputStream("./config/client_secret.json")) {
        credential = GoogleCredential.fromStream(is);
    }
    GoogleCredential credentialWithUser = new GoogleCredential.Builder()
            .setTransport(getDefaultTransport())
            .setJsonFactory(getDefaultJsonFactory())
            .setServiceAccountUser("admin@yourdomain.ru")  // <--- mail of domain's admin
            .setServiceAccountId(credential.getServiceAccountId())
            .setServiceAccountScopes(SCOPES)
            .setServiceAccountPrivateKey(credential.getServiceAccountPrivateKey())
            .setServiceAccountPrivateKeyId(credential.getServiceAccountPrivateKeyId())
            .setTokenServerEncodedUrl(credential.getTokenServerEncodedUrl()).build();

    service = new Directory.Builder(getDefaultTransport(), getDefaultJsonFactory(), credentialWithUser).setApplicationName(APPLICATION_NAME).build();
}

 public void members() throws IOException {
    Members members = service.members().list("groupName@yourdomain.ru").execute();
    System.out.println(members);
 }

对于我的试用 G Suite 帐户,它可以工作!

于 2017-02-18T09:32:15.040 回答
1

您可以按照Google Drive 域范围文档中的说明,在控制面板中授予服务帐户对某些范围的访问权限。只需使用 Admin SDK 范围。

应用程序名称用于请求的 User-Agent 标头中,因此并不太重要,只需使用您的应用程序名称和版本即可。

于 2013-09-02T15:54:53.070 回答