尽管用户列表API正常运行,但无法访问用户监视API返回状态403 先决条件解决方法

问题描述

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

使用与下面相同的设置,我可以访问用户列表API(link)。

但是当尝试向Users Watch API(link)发出请求时,返回了状态403。

这2个API需要使用与我的SA密钥相同的作用域用户。只读。

我的域已通过验证,并已添加到GCP控制台的“域验证”屏幕中。

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("[email protected]")
        .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

解决方法

Google Directory API不直接支持Kotlin,这取决于目标编译

先决条件

确保已激活Delegating domain-wide authority to the service account

解决方法

作为JAVA中的一种方法(您可以根据需要将此代码转换为Kotlin),首先使用官方文档的watch methodChannel class,我将依赖包在评论中:

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("[email protected]");

// 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 Directory API