【发布时间】:2017-01-23 10:08:32
【问题描述】:
我想访问一些 google api 服务:
- GDrive API
- 联系 API
- 人员 API
我正在努力使用 oauth2 模拟服务帐户流程(您知道那个:Google Oauth v2 - service account description。对于模拟,您需要在 google 应用程序控制台中应用“委托域范围的权限”,下载相应的 pk12 文件并在 google 控制台项目中激活 api。
此刻我总是得到:
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 oauthsample.GDriveAPI.<init>(GDriveAPI.java:50)
at oauthsample.GDriveAPI.main(GDriveAPI.java:85)
这是我的代码:
HttpTransport httpTransport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
Set<String> scopes = new HashSet<String>();
scopes.add("https://www.google.com/m8/feeds");
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId("myserviceuser@xxxxxx.iam.account.com")
.setServiceAccountPrivateKeyFromP12File(new File("somep12key.p12"))
.setServiceAccountScopes(scopes)
.setServiceAccountUser("my_user_name@gmail.com")
.build();
credential.refreshToken();
ContactsService service = new ContactsService("MYAPP");
service.getRequestFactory().setHeader("User-Agent", "MYAPP");
service.setHeader("GData-Version", "3.0");
service.setOAuth2Credentials(credential);
URL feedUrl = new URL("https://www.google.com/m8/feeds/contacts/default/full");
ContactFeed resultFeed = service.getFeed(feedUrl, ContactFeed.class);
我还通过 stackoverflow 进行了大量搜索(无法列出所有引用并检查了响应和解决方案)。但是一个问题从来没有得到明确的回答——谷歌的文档和所有的 stackoverflow 帖子都没有:
- 真的可以用普通 user@gmail.com 用户模拟服务帐户吗(我的意思是普通 gmail 帐户无法访问“将域范围的权限委派给服务”一章中提到的管理控制台帐户”并且没有自己的域)?
有人说是,有人说不是。那么什么是绝对真理呢?
据我在阅读谷歌文档时了解:服务帐户只能在您负责自己的域时模拟用户,并且您需要拥有一个注册了您自己的域的谷歌工作帐户。然后,您就可以访问管理控制台并授予对服务帐户的访问权限。
感谢您的耐心等待并抽出时间回答。
最好的问候 马特
【问题讨论】:
-
真的可以冒充服务帐号吗?当我们有客户端登录时,怀疑它可能会回来。我从来没有让它与 Oauth 一起工作。我印象深刻的是,您能够混合发现 API 和 gdata api,这并不容易 :)
-
作为进一步的输入,我只能说上面的代码是大量尝试和错误以及 stackoverflow 解决方案的混合体。我的代码中断的地方是“credential.refreshToken();”行所以我想我无法获得新的授权令牌。是的,你是对的,它是 gdata 和发现 api 的混合体……但这不是重点。您可以实例化任何您想要的服务(People API、Gdrive API,...),除非您有正确且有效的 oauth 凭证设置。
-
服务帐户不需要它。注意:我不是java程序员。
-
你是对的,实际上首先创建新的凭证并再次刷新令牌并没有多大意义。如果我用“credential.refreshToken()”注释掉代码,我的代码会在最后一行出现 NPE:“线程“main”中的异常 java.lang.NullPointerException:没有身份验证头信息”。所以还是不行。很奇怪吧?
标签: java service google-oauth impersonation account