1

所以有点关于这个问题的背景。我有一个本地应用程序,它同时使用 google calendar api 和 google admin sdk 来管理用户日历和资源日历。

这是我在设置中采取的步骤

  • 创建服务帐户并为其授予域范围的访问权限
  • 在开发者控制台中添加并启用了 Google Calendar Api 和 Admin SDK
  • 将客户端 ID 和范围添加到 Gsuit 管理控制台的管理 API 客户端访问部分

我在这里构建凭据(出于测试目的,我将它们存储在本地的 json 文件中)

val JSON_FACTORY: JsonFactory = JacksonFactory.getDefaultInstance()
var HTTP_TRANSPORT: HttpTransport = GoogleNetHttpTransport.newTrustedTransport()
var SCOPES = DirectoryScopes.all()

val cred = new GoogleCredential.Builder()
  .setTransport(HTTP_TRANSPORT)
  .setJsonFactory(JSON_FACTORY)
  .setServiceAccountId(CLIENTID)
  .setServiceAccountScopes(SCOPES)
  .setServiceAccountUser(USER)
  .setServiceAccountPrivateKey(serviceAccountCredJson.getServiceAccountPrivateKey)
  .setServiceAccountPrivateKeyId(serviceAccountCredJson.getServiceAccountPrivateKeyId)
  .build()

cred.refreshToken()

我遇到的第一个问题是如果我删除该行

.setServiceAccountUser(USER)

然后cred.refreshToken() == true但是当我尝试获取my_customer的资源列表时出现此错误

404 Not Found
{
  "code" : 404,
  "errors" : [ {
    "domain" : "global",
    "message" : "Domain not found.",
    "reason" : "notFound"
  } ],
  "message" : "Domain not found."
}
com.google.api.client.googleapis.json.GoogleJsonResponseException: 404 Not Found

如果我冒充用户,我会收到由cred.refreshToken()引起的此错误

401 Unauthorized
com.google.api.client.auth.oauth2.TokenResponseException: 401 Unauthorized
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:384)
at com.google.api.client.auth.oauth2.Credential.refreshToken(Credential.java:489)
at com.iofficeconnect.reservation.google.GoogleDirectoryClient$.getCredsAsUser(GoogleDirectoryClient.scala:96)

我知道,为了操作 Admin SDK,您必须模拟具有管理员凭据的用户,但是即使我这样做,我也会得到相同的结果。


连接到 Admin SDK 的客户端是在这些行中构建的

def getClientAsUser(user:String):Directory={
    new Directory.Builder(HTTP_TRANSPORT, JSON_FACTORY, testCredJsonAsTestUser(user))
      .setApplicationName(APPLICATION_NAME)
      .build()
}

在这些行中执行对 Admin SDK 的最终调用

var client = getClientAsUser(admin@domain.com)
var calendarList = client.resources().calendars().list("my_customer").execute()

任何帮助将不胜感激

4

1 回答 1

0

尝试模拟有权访问 Directory API 的管理员。根据文件

只有有权访问 Admin API 的用户才能访问 Admin SDK Directory API,因此您的服务帐户需要模拟其中一位用户才能访问 Admin SDK Directory API。

此外,检查这些相关的 SO 后管理员用户获取 google 日历资源列表TokenResponseException: 401 Unauthorized Exception 尝试访问 Admin SDK Google API 时。第一个相关的 SO 帖子指出访问日历资源需要超级管理员,第二个帖子指出TokenResponseException: 401 Unauthorized在客户端 ID、客户端密码或范围无效时发生。但这也可能是由于刷新令牌过度使用造成的。

希望这可以帮助。

于 2017-04-07T15:07:24.120 回答