【问题标题】:Google Admin SDK: 401 Unauthorized using .setServiceAccountUser()Google Admin SDK:401 Unauthorized using .setServiceAccountUser()
【发布时间】:2017-09-02 01:22:42
【问题描述】:

关于这个问题的一些背景知识。我有一个本地应用程序,它同时使用 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()

任何帮助将不胜感激

【问题讨论】:

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


    【解决方案1】:

    尝试冒充有权访问 Directory API 的管理员。根据document

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

    另外,请查看这些相关的 SO 帖子 - admin users get list of google calendar resourcesTokenResponseException: 401 Unauthorized Exception when trying to access Admin SDK Google API。第一个相关的 SO 帖子指出访问日历资源需要超级管理员,第二个帖子指出 TokenResponseException: 401 Unauthorized 在客户端 ID、客户端密码或范围无效时发生。但这也可能是由于过度使用刷新令牌造成的。

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-05
      • 1970-01-01
      • 1970-01-01
      • 2022-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多