Google cloud platform 获取服务帐户的访问令牌时出错:使用服务帐户使用日历API时401未经授权

Google cloud platform 获取服务帐户的访问令牌时出错:使用服务帐户使用日历API时401未经授权,google-cloud-platform,google-calendar-api,google-workspace,google-client,google-auth-library,Google Cloud Platform,Google Calendar Api,Google Workspace,Google Client,Google Auth Library,我有一个具有域范围委派设置的服务帐户,我正在尝试使用该服务帐户创建新帐户(google api services admin directory),然后向新创建的帐户添加一些预设日历(google api services calendar) 我对目录api没有任何问题。我必须使用服务帐户创建一个委托(管理员)用户,所有目录api调用都可以正常工作 然而,我在让日历api调用正常工作方面遇到了麻烦 Java依赖项: compile group: 'com.google.auth', name:

我有一个具有域范围委派设置的服务帐户,我正在尝试使用该服务帐户创建新帐户(google api services admin directory),然后向新创建的帐户添加一些预设日历(google api services calendar)

我对目录api没有任何问题。我必须使用服务帐户创建一个委托(管理员)用户,所有目录api调用都可以正常工作

然而,我在让日历api调用正常工作方面遇到了麻烦

Java依赖项:

compile group: 'com.google.auth', name: 'google-auth-library-oauth2-http', version:'0.20.0'
compile group: 'com.google.apis', name: 'google-api-services-admin-directory', version:'directory_v1-rev53-1.20.0'
compile group: 'com.google.apis', name: 'google-api-services-calendar', version:'v3-rev20200315-1.30.9'

Java代码:

private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private static final List<String> SCOPES = 
Arrays.asList(DirectoryScopes.ADMIN_DIRECTORY_USER, DirectoryScopes.ADMIN_DIRECTORY_GROUP,
      CalendarScopes.CALENDAR);
private static final String CREDENTIALS_FILE_PATH = "config/google-service-account-credentials.json";
.....
HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
sourceCredentials =
          ServiceAccountCredentials.fromStream(new FileInputStream(CREDENTIALS_FILE_PATH));
sourceCredentials = (ServiceAccountCredentials) sourceCredentials.createScoped(SCOPES);

.....

GoogleCredentials targetCredentials = sourceCredentials.createDelegated("newuser@email");
  HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(targetCredentials);
  targetCredentials.refreshIfExpired();//Not sure if this is required. It didn't help though
  Calendar calendarService = new Calendar.Builder(HTTP_TRANSPORT, JSON_FACTORY, requestInitializer).setApplicationName(MainApp.SERVICE_NAME).build();

  for (String calendarKey : listOfCalendars)) {
    CalendarListEntry cle = new CalendarListEntry();
    cle.setId(calendarKey);
    calendarService.calendarList().insert(cle).execute();//Fails with a 401
  }
有趣的是,误差是间歇性的。在重新部署之后,我总能第一次尝试工作。在这之后,它是一个命中或未命中

  • 我确实将服务帐户添加到了我尝试添加的日历中,并确保服务帐户是日历上的“所有者”

    • 类似的事情发生在我身上,在我的情况下,我可以通过添加作用域来解决它:
      “https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/userinfo.profile“

      类似的事情发生在我身上,我可以通过添加作用域来解决它:
      ”https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/userinfo.profile“

      自从运行API调用以来,您是否更改了任何作用域?您能否刷新令牌(即删除并生成新令牌)以确保这不是问题所在?另外,如果您尝试将日历API与该服务帐户单独使用,而不使用目录API,您是否能够调用日历API?让我知道进展如何。谢谢我没有改变范围。我在Java代码中有3个作用域,在Google管理(安全)控制台中有API访问列表和客户端ID。我使用服务帐户来运行API,因此我不会手动存储/缓存任何令牌。我的理解是,客户端库将在需要时(过期)刷新令牌,这似乎是问题的一部分。当你说日历API没有目录API时,我是否也应该将作用域更改为日历API?谢谢即使在Java和API Access管理控制台中都有这三个作用域,如果我将Java代码限制为只调用日历API(而不是目录API),我也会看到成功。我确实注意到过几次SocketException,但从未注意到401。自从运行API调用以来,您是否更改了任何作用域?您能否刷新令牌(即删除并生成新令牌)以确保这不是问题所在?另外,如果您尝试将日历API与该服务帐户单独使用,而不使用目录API,您是否能够调用日历API?让我知道进展如何。谢谢我没有改变范围。我在Java代码中有3个作用域,在Google管理(安全)控制台中有API访问列表和客户端ID。我使用服务帐户来运行API,因此我不会手动存储/缓存任何令牌。我的理解是,客户端库将在需要时(过期)刷新令牌,这似乎是问题的一部分。当你说日历API没有目录API时,我是否也应该将作用域更改为日历API?谢谢即使在Java和API Access管理控制台中都有这三个作用域,如果我将Java代码限制为只调用日历API(而不是目录API),我也会看到成功。我有好几次注意到SocketException,但从来没有注意到401。
      Caused by: java.io.IOException: Error getting access token for service account: 401 Unauthorized
      at com.google.auth.oauth2.ServiceAccountCredentials.refreshAccessToken(ServiceAccountCredentials.java:444)
      at com.google.auth.oauth2.OAuth2Credentials.refresh(OAuth2Credentials.java:157)
      at com.google.auth.oauth2.OAuth2Credentials.refreshIfExpired(OAuth2Credentials.java:174)
      at myApp.GSuiteSDKHelper.updateDefaultCalendars(GSuiteSDKHelper.java:169)
      ... 65 more
      Caused by: com.google.api.client.http.HttpResponseException: 401 Unauthorized
      at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1113)
      at com.google.auth.oauth2.ServiceAccountCredentials.refreshAccessToken(ServiceAccountCredentials.java:441)
      ... 68 mo