java - 我是否需要 G Suite 帐户才能通过服务帐户冒充用户发出请求?

标签 java google-api google-drive-api google-oauth

我尝试使用服务帐户模拟用户向 Drive API 发出请求,但收到 TokenResponseException: 401 Unauthorized 异常。

我已按照 https://developers.google.com/identity/protocols/OAuth2ServiceAccount 中的描述进行操作:

然后,在我的代码中:

File p12 = new File("p12FileFromDevelopersConsole.p12");
HttpTransport transport = GoogleNetHttpTransport.newTrustedTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();

GoogleCredential c = new GoogleCredential.Builder()
    .setTransport(transport)
    .setJsonFactory(jsonFactory)
    .setServiceAccountId("MY_ID@MY-ID.iam.gserviceaccount.com")
    .setServiceAccountUser("test@gmail.com")
    .setServiceAccountScopes(Arrays.asList(DriveScopes.DRIVE, DriveScopes.DRIVE_APPDATA, DriveScopes.DRIVE_FILE, DriveScopes.DRIVE_METADATA_READONLY))
    .setServiceAccountPrivateKeyFromP12File(p12)
    .build();

List<com.google.api.services.drive.model.File> files = drive.files()
    .list()
    .setSpaces("drive")
    .setFields("nextPageToken, files(id, name, webViewLink)")
    .setPageSize(10)
    .execute() // < --- exception is thrown here
    .getFiles();

for(com.google.api.services.drive.model.File f : files) {
    System.out.println(f.getName());
}

堆栈跟踪是:

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.google.api.client.auth.oauth2.Credential.intercept(Credential.java:217)
    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:868)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)

我可以注意到,如果我注释掉 .setServiceAccountUser("test@gmail.com") 行,我就能够执行代码,并且它会在我的 中打印“入门” System.out.println.

我看过很多关于这个问题的帖子,但没有一个给出具体的解决方案。然后,我查看了上面引用的文档,其中多次提及 G Suite,然后我意识到这些请求可能仅适用于 G Suite 帐户。我对吗?如果没有,我怎样才能让它工作?

最佳答案

是的,服务帐户的域范围委派仅适用于 GSuite 用户,因为 GSuite 管理员必须授予服务帐户域范围权限 - 请参阅此处的步骤 4:https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority

考虑使用常规 OAuth ( https://developers.google.com/identity/protocols/OAuth2WebServer ) 授予从您的 Gmail 帐户访问您的网络应用程序的权限。

关于java - 我是否需要 G Suite 帐户才能通过服务帐户冒充用户发出请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45848650/

相关文章:

java - Hibernate Apache Derby 自定义序列

c++ - 如何将参数传递给Google Benchmark计划

apache - 使用 Google Drive Directory 作为 Apache 虚拟主机

google-drive-api - files.list() 可重现地返回 "drive.files"范围内的不完整列表

javascript - 使用谷歌选择器选择文件夹

java - 重新定义方法会覆盖以前的重新定义

java - 不使用数组的斐波那契数列

java - 我可以使用什么来跟踪按下了哪个按钮?

javascript - Google Storage API - 可恢复上传、AJAX、CORS 错误

javascript - 谷歌日历 API React 'gapi not found'