问题描述
我使用带有范围(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 method和Channel 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());