因此,在显示我的代码之前,让我解释我采取了哪些步骤以“正确”设置服务帐户环境。Google管理员目录API,错误请求400 invalid_grant。 (使用服务帐户)
- 在谷歌开发者控制台中,创建了服务帐户。 (这产生了客户ID(这是一个很长的数字),服务帐户([email protected])和我在P12中下载的私钥
- 在管理控制台中,将客户ID放在合适的范围在我的情况下,我加入了范围是
https://www.googleapis.com/auth/admin.directory.group.readonly
和https://www.googleapis.com/auth/admin.directory.group.member.readonly
在我的代码,正确设置了专用密钥的路径和其他环境
def getDirectoryService: Directory = { val httpTransport: HttpTransport = new NetHttpTransport() val jsonFactory: JacksonFactory = new JacksonFactory() val credential: GoogleCredential = new GoogleCredential.Builder() .setTransport(httpTransport) .setJsonFactory(jsonFactory) .setServiceAccountId("[email protected]") .setServiceAccountScopes(util.Arrays.asList(DirectoryScopes.ADMIN_DIRECTORY_GROUP_READONLY, DirectoryScopes.ADMIN_DIRECTORY_GROUP_MEMBER_READONLY)) .setServiceAccountUser("[email protected]") .setServiceAccountPrivateKeyFromP12File( new java.io.File("/pathToKey/privatekey.p12")) .build() val service: Directory = new Directory.Builder(httpTransport, jsonFactory, null) .setHttpRequestInitializer(credential).build() service }
然后我尝试这样执行的东西:。
service.groups().list().execute()
或
service.groups().list("domain.com").execute()
该代码将导致,
com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request
{
"error" : "invalid_grant"
}
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)
at com.company.project.GoogleServiceProvider.getGroups(GoogleServiceProvider.scala:81)
at com.company.project.ProjectHandler.handle(ProjectHandler.scala:110)
at com.company.common.web.DispatcherServlet.service(DispatcherServlet.scala:40)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:845)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:583)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:224)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1174)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:511)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1106)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)
at org.eclipse.jetty.server.Server.handle(Server.java:524)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:319)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:253)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95)
at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93)
at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303)
at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148)
at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589)
at java.lang.Thread.run(Thread.java:745)
什么可能是我做错了什么?我一直在寻找过去两天的解决方案,并尝试了很多事情。我还不确定的解决方案之一是ntp同步(如何将服务器时间完全同步到ntp)。
任何adivce会很有帮助,谢谢!
更新:我还确保激活管理目录SDK,并在开发者控制台上启用了域范围委派。
更新#2:我忘了提及,管理员帐户不是项目本身的所有者。所以基本上,我是一个域的成员,并且我创建了一个项目,所以我是该项目和服务帐户的唯一所有者(我不是管理员)。但是,如果管理员是项目的所有者并创建服务帐户才能正常工作?
您是否尝试将setServiceAccountUser设置为服务帐户的电子邮件地址? – DaImTo
Shouldnt serviceAccountUser是我想模仿的人的电子邮件地址?如果我使用serviceAccountUser的服务帐户电子邮件地址,我会为serviceAccountId放什么? – Sardonic
服务帐户本身就是一个虚拟用户。 – DaImTo