Google Admin SDK:401未经授权使用.setServiceAccountUser()

时间:2017-04-06 20:10:10

标签: google-calendar-api google-admin-sdk service-accounts google-developers-console gsuite

关于这个问题的一些背景知识。我有一个本地应用程序,使用谷歌日历api和谷歌管理员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()

非常感谢任何帮助

1 个答案:

答案 0 :(得分:0)

尝试模拟有权访问Directory API的管理员。根据{{​​3}}:

  

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

另外,请检查这些相关的SO帖子 - documentadmin users get list of google calendar resources。第一篇相关的SO帖子声称,访问日历资源需要超级管理员,第二篇文章声明,当拥有无效的客户端ID,客户端密码或范围时,会发生 TokenResponseException:401 Unauthorized 。但也可能是因为刷新令牌过度使用。

希望这有帮助。