Google Admin SDK 与服务帐户没有模拟

Google Admin SDK with service account without impersonation

目标是在 G-Suite 平台中建立一个服务帐户,应用程序可以使用该服务帐户执行操作而无需提示用户进行身份验证。

我们遇到的问题与以下帖子非常相似,但略有不同。

只要我们遵循“模拟”流程,事情就可以进行。通过模拟,授权规则遵循被模拟的用户。理想情况下,我们希望相应地确定服务帐户的范围,而不是模拟用户。当我们这样做时这,我们不断收到 403。

我们已尽力按照此处的说明进行操作:

我们的 Java 片段与此类似:

    final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();

    File file = new File(MdmResource.class.getClassLoader().getResource("myproject.p12").getFile());

    GoogleCredential credential = new GoogleCredential.Builder()
        .setTransport(HTTP_TRANSPORT)
        .setJsonFactory(JSON_FACTORY)
        .setServiceAccountId("105601508644514129999")
        .setServiceAccountPrivateKeyFromP12File(file)
        .setServiceAccountScopes(
             Collections.singletonList(DirectoryScopes.ADMIN_DIRECTORY_USER_READONLY))
        .setServiceAccountUser("user@domain.com")  // 403 when this is commented out
        .build();

    Directory dir = new Directory(HTTP_TRANSPORT, JSON_FACTORY, credential);
    Get result = dir.users().get("dude@domain.com");
    User user = result.execute();
    System.out.println(user.get("customerId"));

在 GCP 中,我们在以超级管理员身份登录时创建了 ServiceAccount。我们启用了全域委托并生成了密钥(在这个例子中,p12 类型并使用相应的文件作为 Java 应用程序的输入)。

然后,在 API 库中,我们启用了 Admin SDK

在 Google 管理员中,在 Security/Advanced 设置下,我们设置范围。我们使用了 105601508644514129999 和 https://www.googleapis.com/auth/admin.directory.device.mobile,https://www.googleapis.com/auth/admin.directory.user.readonly,https://www.googleapis.com/auth/admin.directory.user

当我们 运行 Java 代码时,当 "setServiceAccountUser" 被注释掉时,我们会看到以下内容(只要用户具有正确的权限,模拟时就可以正常工作):

{
  "code" : 403,
  "errors" : [ {
    "domain" : "global",
    "message" : "Not Authorized to access this resource/api",
    "reason" : "forbidden"
  } ],
  "message" : "Not Authorized to access this resource/api"
}

所以,我们的 SA 似乎没有正确连接到范围,但我不知道该怎么做。

顺便说一句,105601508644514129999 是在 SA 创建过程中自动生成的 OAuth 2.0 凭据的 SA 唯一 ID 和客户端 ID。我们还使用了 "setServiceAccountId" 的 SA 电子邮件,如下例所示,但仍然收到 403。https://developers.google.com/admin-sdk/directory/v1/guides/delegation。实际上,我认为这个例子还有另一个关于 .setServiceAccountScopes 的问题。

终于...

        <dependency>
            <groupId>com.google.auth</groupId>
            <artifactId>google-auth-library-oauth2-http</artifactId>
            <version>0.20.0</version>
        </dependency>

        <!-- Used to navigate Google Directory services, like https://developers.google.com/admin-sdk/directory -->
        <dependency>
            <groupId>com.google.apis</groupId>
            <artifactId>google-api-services-admin-directory</artifactId>
            <version>directory_v1-rev117-1.25.0</version>
        </dependency>

有什么想法吗?

服务帐户不在 G Suite 域中(即使它们属于其中的用户/项目),因此无法授予对 G Suite 域的管理员访问权限。他们所能做的就是通过全域委派模拟域中的用户。

您可能想要解决的问题是使用客户端 ID 和密码作为管理员用户授予常规 OAuth,并确保获得长期有效的刷新令牌 access_type=offline。这将允许您在访问令牌过期时刷新访问令牌,并继续充当单个管理员用户,只要他们不撤销您的访问权限即可。