使用服务帐户调用Java Google Drive API时无效的授权 [英] Invalid grant when calling Java Google Drive Api with Service Account

查看:262
本文介绍了使用服务帐户调用Java Google Drive API时无效的授权的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

确定!正如标题所述,我在使用服务帐户时遇到了一些认证问题。所以让我们从头开始,因为我觉得我已经尝试了所有的东西!



服务设置为开:





Drive SDK设置:



服务帐户Api访问权限



此处:


Ok! As the title states I'm having some serious issues with the authentication when using a Service Account. So let's start from the beginning since it feels that I have tried everything!

Services set to on:

Drive SDK setup:

Service Account Api Access:

Api client access as described here: http://support.google.com/a/bin/answer.py?hl=en&answer=162106

The code:

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.
        }
}

The exception:

[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)

I've been browsing the web for the past 3 hours and all of the PHP and Python folks seem to have solved it by setting the correct time on their linux production server. I'm sitting in MacOS Snow Leopard and I have tried with the time setting but no luck there. I have also tried to create a new key. Changing the scopes. Adding different ServiceAccountUsers and so on. I'm probably missing some crucial part or maybe it's supersimple? I'm running out of ideas!

解决方案

Did you try the single scope:

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

and,

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

should be

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

The other scopes are required for the Spreadsheets, they are not required (yet).

also, see this related question

这篇关于使用服务帐户调用Java Google Drive API时无效的授权的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆