Google api Google目录API在调用用户()时返回Not Authorized().list().execute()

Google api Google目录API在调用用户()时返回Not Authorized().list().execute(),google-api,google-api-java-client,google-admin-sdk,Google Api,Google Api Java Client,Google Admin Sdk,我需要从我的谷歌域名中读取用户(和组)列表 因此,我转到我的谷歌API控制台,启用了管理SDK,并创建了一个服务帐户来调用谷歌API。我使用以下google库 google-api-services-admin-directory_v1-rev11-1.16.0-rc.jar google-api-client-1.16.0-rc.jar 我的代码是 /* * Global instance of the JSON factory. */ final J

我需要从我的谷歌域名中读取用户(和组)列表

因此,我转到我的谷歌API控制台,启用了管理SDK,并创建了一个服务帐户来调用谷歌API。我使用以下google库

  • google-api-services-admin-directory_v1-rev11-1.16.0-rc.jar
  • google-api-client-1.16.0-rc.jar
我的代码是

     /*
     * 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();
如果我取消注释注释注释行(
.setServiceAccountUser(“admin@mydomain.org)然后我得到一个不同的错误

    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)
我的帐户(admin@mydomain.org)是超级管理员。我怀疑需要授予服务帐户对用户API范围的访问权限。但是我找不到在哪里可以授予此访问权限。我有一个典型的谷歌CPanel用户界面模式。我在高级工具中没有“管理客户端API访问”页面

另外,我不确定在
.setApplicationName(“Test”)
中应该使用什么作为应用程序名


感谢您的帮助

您可以授予服务帐户访问控制面板中特定作用域的权限,如中所述。只需使用ADMINSDK作用域即可

应用程序名称用于请求的用户代理标题中,因此不太重要,只需使用应用程序名称,可能还有版本即可。

您可以在管理控制台(admin.google.com/AdminHome?chromeless=1&pli=1#SecuritySettings:)中转到“安全”设置;然后单击高级设置>管理第三方OAuth客户端访问。在此之后,映射您的客户端id(在oath2的API访问下从appconsole code.google.com/API/console生成)和“一个或多个API范围”。如前所述,使用逗号分隔的作用域。对于谷歌目录,您可以使用


希望在这之后它能起作用:)

我遇到了完全相同的问题,并且被绊住了

帮助我的是: 1/我没有,正如Jay Lee所建议的那样。但在那之后,我仍然有问题。
2/然后,根据,调用setServiceAccountUser(yourAdminAccount@yourDomain.com)是必需的。

谷歌目录API与计算引擎默认服务帐户配合使用,您无需在整个域范围内设置谷歌驱动器。唯一的问题是:必须设置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);
 }
import static com.google.api.client.googleapis.util.Utils.getDefaultJsonFactory;
导入静态com.google.api.client.googleapis.util.Utils.getDefaultTransport;
私有静态最终字符串应用程序\u NAME=“AnyAppName”;
私有最终列表范围=ImmutableList.of(
DirectoryScopes.ADMIN\u目录\u组成员,DirectoryScopes.ADMIN\u目录\u用户,DirectoryScopes.ADMIN\u目录\u组);
专用目录服务;
@施工后
void init()引发GeneralSecurityException,IOException{
谷歌认证证书;
try(InputStream=newfileinputstream(“./config/client\u secret.json”)){
凭证=GoogleCredential.fromStream(is);
}
GoogleCredentialCredentialWithUser=新建GoogleCredential.Builder()
.setTransport(getDefaultTransport())
.setJsonFactory(getDefaultJsonFactory())

.setServiceAccountUser(“admin@yourdomain.ru“”//谢谢您的回复。我找不到此“管理第三方OAuth客户端访问”我的控制面板中的高级工具中的项,如Google Drive文档中所述。可能我需要以某种方式启用它?请参阅:。上的说明。听起来您可能启用了新的管理控制台。我找不到此“管理客户端API访问”页面。我添加了一张我的高级工具的图片。可能我需要启用一些东西?你正在使用哪个版本的谷歌应用?(教育、商业、免费/标准)?我使用的是Google Apps Partner Edition。我有经典的管理控制台。页面位于其他位置。我使用的是试用帐户,没有此选项,只是说“管理OAuth客户端访问”。这是因为试用还是需要一些配置
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);
 }