首页 > 解决方案 > 尽管用户列表 API 正常工作,但无法访问用户监视 API(返回状态 403)

问题描述

我使用具有范围 ( https://www.googleapis.com/auth/admin.directory.user.readonly ) 的服务帐户密钥来访问 Google Directory API 用户。

通过与以下相同的设置,我可以访问用户列表 API(链接)。

但是当尝试向用户观察 API(链接)发出请求时,状态 403 返回。

这 2 个 API 需要与我的 SA 密钥具有相同范围的 user.readonly。

我的域已经过验证并添加到 GCP Console 的域验证屏幕中。

val httpTransport = GoogleNetHttpTransport.newTrustedTransport()
val jsonFactory = JacksonFactory()
val inputStream = HealthController::class.java.getResourceAsStream("/credentials.json")
        ?: throw FileNotFoundException("/credentials.json")
val credential = GoogleCredential.fromStream(inputStream, httpTransport, jsonFactory)
        .toBuilder()
        .setServiceAccountScopes(listOf(DirectoryScopes.ADMIN_DIRECTORY_USER_READONLY))
        .setServiceAccountUser("admin@example.com")
        .build()
service = Directory.Builder(httpTransport, jsonFactory, credential)
        .setApplicationName("Some Name")
        .build()

val channel = Channel()
channel.address = "https://example.com/webhook/v1/google/users"
channel.expiration = Instant.now().toEpochMilli() + 6 * 60 * 60 * 1000
channel.id = "webhook001"
channel.token = "abcxyz"
channel.type = "web_hook"
channel.payload = false

val result = service.users().watch(channel)
        .setDomain("example.com")
        .setViewType("domain_public")
        .execute()

我将问题记录到 Google 问题跟踪器:https ://issuetracker.google.com/issues/171300784

标签: kotlingoogle-admin-sdkgoogle-directory-api

解决方案


Google Directory API 不直接支持 Kotlin,它依赖于目标编译

先决条件

确保您已激活向服务帐户委派域范围的权限。

解决方法

作为 JAVA 中的一种方法(如果需要,您可以将此代码转换为 Kotlin)首先使用官方文档的watch 方法以及Channel 类,我将包依赖项放在注释中:

JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
NetHttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();

// com.google.auth.oauth2.ServiceAccountCredentials
GoogleCredentials credentials = ServiceAccountCredentials.fromStream(new FileInputStream(SERVICE_ACCOUNT_CREDENTIALS_FILE_PATH))
            .createScoped(SCOPES)
            .createDelegated("impersonated@example.com");

// com.google.api.client.http
HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credentials);

// com.google.api.services.admin.directory.Directory.Builder
Directory service = new Directory.Builder(httpTransport, jsonFactory, requestInitializer)
                .setApplicationName(APPLICATION_NAME)
                .build();

// com.google.api.services.admin.directory.model.Channel
Channel channel = new Channel();
channel.setAddress("https://example.com/webhook/v1/google/users");
channel.setExpiration(Instant.now().toEpochMilli() + 6 * 60 * 60 * 1000);
channel.setId("webhook001");
channel.setToken("abcxyz");
channel.setType("web_hook");
channel.setPayload(false);

System.out.println(service.users().watch(channel)
                .setDomain("example.com")
                .setViewType("domain_public")
                .execute());

参考

Javadoc 目录 API


推荐阅读