java - 使用服务帐户调用 Java Google Drive Api 时授予无效

标签 java google-api google-drive-api

好的!正如标题所述,我在使用服务帐户时遇到了一些严重的身份验证问题。所以还是从头开始吧,感觉自己什么都试过了!

服务设置为开启:

enter image description here

Drive SDK 设置:

enter image description here

服务帐户 API 访问:

enter image description here

此处描述的 Api 客户端访问:http://support.google.com/a/bin/answer.py?hl=en&answer=162106

enter image description here

代码:

public static void callSpreadsheetApi() {

        GoogleCredential credential = null;
        try {
            credential = new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT)
                    .setJsonFactory(JSON_FACTORY)                    
                    .setServiceAccountId("2363XXXXXX19.apps.googleusercontent.com")                    
                    .setServiceAccountScopes(DriveScopes.DRIVE, "https://spreadsheets.google.com/feeds", "https://docs.google.com/feeds")
                    .setServiceAccountPrivateKeyFromP12File(new File("/Users/stevesmith/Desktop/c02e064935d33c3389f6ab1dbf9ea747a5bdaac5-privatekey.p12"))
                    .setServiceAccountUser("steve.smith@reco.se")
                    .build();

        } catch (GeneralSecurityException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }


        Drive drive = new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential).build();

        com.google.api.services.drive.model.File  file = new com.google.api.services.drive.model.File();
        file.setTitle("test");
        file.setMimeType("application/vnd.google-apps.spreadsheet");
        Drive.Files.Insert insert = null;
        try {
            insert = drive.files().insert(file);
            file = insert.execute();
        } catch (IOException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
}

异常:

[info] play - Application started (Dev)
com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request
{
  "error" : "invalid_grant"
}
    at com.google.api.client.auth.oauth2.TokenResponseException.from(TokenResponseException.java:103)
    at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:303)
    at com.google.api.client.auth.oauth2.TokenRequest.execute(TokenRequest.java:323)
    at com.google.api.client.googleapis.auth.oauth2.GoogleCredential.executeRefreshToken(GoogleCredential.java:340)
    at com.google.api.client.auth.oauth2.Credential.refreshToken(Credential.java:505)
    at com.google.api.client.auth.oauth2.Credential.intercept(Credential.java:266)
    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:857)
    at com.google.api.client.googleapis.json.GoogleJsonResponseException.execute(GoogleJsonResponseException.java:182)
    at com.google.api.client.googleapis.services.GoogleClient.executeUnparsed(GoogleClient.java:279)
    at com.google.api.client.http.json.JsonHttpRequest.executeUnparsed(JsonHttpRequest.java:207)
    at com.google.api.services.drive.Drive$Files$Insert.executeUnparsed(Drive.java:307)
    at com.google.api.services.drive.Drive$Files$Insert.execute(Drive.java:331)
    at services.GoogleService.callSpreadsheetApi(GoogleService.java:236)
    at controllers.Application.index(Application.java:26)
    at Routes$$anonfun$routes$1$$anonfun$apply$1$$anonfun$apply$2.apply(routes_routing.scala:32)
    at Routes$$anonfun$routes$1$$anonfun$apply$1$$anonfun$apply$2.apply(routes_routing.scala:32)
    at play.core.Router$HandlerInvoker$$anon$5$$anon$1.invocation(Router.scala:1090)
    at play.core.j.JavaAction$$anon$1.call(JavaAction.scala:33)
    at play.core.j.JavaAction$class.apply(JavaAction.scala:74)
    at play.core.Router$HandlerInvoker$$anon$5$$anon$1.apply(Router.scala:1089)
    at play.core.ActionInvoker$$anonfun$receive$1$$anonfun$6.apply(Invoker.scala:126)
    at play.core.ActionInvoker$$anonfun$receive$1$$anonfun$6.apply(Invoker.scala:126)
    at play.utils.Threads$.withContextClassLoader(Threads.scala:17)
    at play.core.ActionInvoker$$anonfun$receive$1.apply(Invoker.scala:125)
    at play.core.ActionInvoker$$anonfun$receive$1.apply(Invoker.scala:115)
    at akka.actor.Actor$class.apply(Actor.scala:318)
    at play.core.ActionInvoker.apply(Invoker.scala:113)
    at akka.actor.ActorCell.invoke(ActorCell.scala:626)
    at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:197)
    at akka.dispatch.Mailbox.run(Mailbox.scala:179)
    at akka.dispatch.ForkJoinExecutorConfigurator$MailboxExecutionTask.exec(AbstractDispatcher.scala:516)
    at akka.jsr166y.ForkJoinTask.doExec(ForkJoinTask.java:259)
    at akka.jsr166y.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:975)
    at akka.jsr166y.ForkJoinPool.runWorker(ForkJoinPool.java:1479)
    at akka.jsr166y.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:104)

过去 3 小时我一直在浏览网页,所有 PHP 和 Python 人员似乎都通过在他们的 Linux 生产服务器上设置正确的时间来解决这个问题。我坐在 MacOS Snow Leopard 中,我尝试过时间设置,但没有运气。我还尝试创建一个新 key 。更改范围。添加不同的 ServiceAccountUsers 等等。我可能遗漏了一些关键部分,或者它可能非常简单?我的想法用完了!

最佳答案

你试过单作用域吗:

 .setServiceAccountScopes("https://www.googleapis.com/auth/drive")

和,

 .setServiceAccountId("23636812XXXX.apps.googleusercontent.com") 

应该是

 .setServiceAccountId("2363681XXXX@developer.gserviceaccount.com")

电子表格需要其他范围,但(目前)还不需要。

另请参阅相关的 question

关于java - 使用服务帐户调用 Java Google Drive Api 时授予无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13253955/

相关文章:

java - 更新: No Resource Found后android studio中的资源错误

java - 获取 GridPane 列/行的宽度/高度?

java - Spring 无版本 xsd 的 Intellij 错误 xsd 验证

java - 谷歌API错误: Null Pointer Exception (Is Google API recently made un available by google?)

oauth - Drive API 的 Google API OAuth 不起作用。获取错误 : origin_mismatch

java - 观察者模式 vs 事件总线消息方法

javascript - Google map js api 在纯 html 页面中工作正常,但在 asp.net mvc 页面中不起作用

google-api - 已经有 Google+ API 了吗?

ios - 如何快速使用 Google Sign-In API

google-drive-api - 在 Google Colab 中安装 Google Drive 的持久授权