Google Admin Directory API, неверный запрос 400 invalid_grant. (используя сервисный аккаунт)

Поэтому, прежде чем показывать свой код, позвольте мне объяснить, какие шаги я предпринял для «правильной» настройки среды учетной записи службы.

  1. В консоли разработчика google создан сервисный аккаунт. (полученный идентификатор клиента (длинный номер), учетная запись службы ([email protected]) и закрытый ключ, который я загрузил в P12.
  2. В консоли администратора укажите идентификатор клиента с соответствующей областью действия. В моем случае я добавил осциллографы https://www.googleapis.com/auth/admin.directory.group.readonly и https://www.googleapis.com/auth/admin.directory.group.member.readonly.
  3. В моем коде правильно настроил путь к закрытому ключу и другие среды.

    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
    }
    
  4. А затем я пытаюсь выполнить что-то вроде этого:

    service.groups().list().execute()  
    

or

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

Любая реклама будет очень полезна, спасибо!

ОБНОВЛЕНИЕ: я также активировал Admin Directory SDK и включил делегирование домена в консоли разработчика.

ОБНОВЛЕНИЕ № 2: я забыл упомянуть, что учетная запись администратора не является владельцем самого проекта. По сути, я являюсь членом домена и создал проект, поэтому я единственный владелец проекта и учетной записи службы (я не администратор). Но должен ли админ быть владельцем проекта и создавать учетную запись службы, чтобы это работало правильно ???


person Sardonic    schedule 06.07.2016    source источник
comment
Вы пробовали установить setServiceAccountUser на адрес электронной почты учетной записи службы?   -  person DaImTo    schedule 07.07.2016
comment
Разве serviceAccountUser не должен быть адресом электронной почты человека, которого я пытаюсь выдать за другое лицо? Если я использую адрес электронной почты учетной записи службы для serviceAccountUser, что мне указывать для serviceAccountId?   -  person Sardonic    schedule 07.07.2016
comment
Учетная запись службы сама по себе является фиктивным пользователем.   -  person DaImTo    schedule 07.07.2016
comment
Кстати, спасибо за быстрый повтор! Итак, с моими текущими настройками, что мне добавить в serviceAccountId и serviceAccountUser? Прямо сейчас я помещаю адрес электронной почты моей учетной записи службы [email protected] в serviceAccountId и [email protected] в serviceAccountUser. Это неправильно?   -  person Sardonic    schedule 07.07.2016
comment
Привет, я поместил второе обновление в исходный пост: TL; DR; admin не является владельцем проекта и учетной записи службы. Могло ли это быть проблемой?   -  person Sardonic    schedule 07.07.2016


Ответы (1)


Хорошо, моя проблема заключалась в том, что в setServiceAccountUser я указал адрес электронной почты группы администраторов, а не фактическую учетную запись пользователя. Судя по всему, это не позволяет поместить адрес электронной почты (псевдоним) группы в setServiceAccountUser. Итак, после ввода реальной учетной записи пользователя с правами администратора, похоже, он работает.

Я все еще задаюсь вопросом, что было бы лучше всего. Например, должен ли я создать отдельную учетную запись пользователя с правами администратора только для проекта? Я определенно не хочу просто вводить адрес электронной почты учетной записи администратора в свой код.

person Sardonic    schedule 07.07.2016
comment
Я видел этот вопрос несколько раз, к сожалению, у меня нет учетной записи администратора Google, поэтому я не могу его проверить. Если то, что вы сделали, работает, придерживайтесь этого :) - person DaImTo; 08.07.2016