0

因此,在顯示我的代碼之前,讓我解釋我採取了哪些步驟以「正確」設置服務帳戶環境。Google管理員目錄API,錯誤請求400 invalid_grant。 (使用服務帳戶)

  1. 在谷歌開發者控制檯中,創建了服務帳戶。 (這產生了客戶ID(這是一個很長的數字),服務帳戶([email protected])和我在P12中下載的私鑰
  2. 在管理控制檯中,將客戶ID放在合適的範圍在我的情況下,我加入了範圍是https://www.googleapis.com/auth/admin.directory.group.readonlyhttps://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() 
    

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:我忘了提及,管理員帳戶不是項目本身的所有者。所以基本上,我是一個域的成員,並且我創建了一個項目,所以我是該項目和服務帳戶的唯一所有者(我不是管理員)。但是,如果管理員是項目的所有者並創建服務帳戶才能正常工作?

+0

您是否嘗試將setServiceAccountUser設置爲服務帳戶的電子郵件地址? – DaImTo

+0

Shouldnt serviceAccountUser是我想模仿的人的電子郵件地址?如果我使用serviceAccountUser的服務帳戶電子郵件地址,我會爲serviceAccountId放什麼? – Sardonic

+0

服務帳戶本身就是一個虛擬用戶。 – DaImTo

回答

1

好吧,我的問題是,在setServiceAccountUser我把管理員組的電子郵件地址,而不是實際的用戶帳戶。顯然,它不允許將組電子郵件(別名)地址放入setServiceAccountUser。 因此,在加入具有管理員權限的實際用戶帳戶後,它似乎正在工作。

我仍然想知道最好的做法是什麼。如在,我應該創建一個單獨的管理員權限的用戶帳戶只是項目?我絕對不想在我的代碼中輸入管理員帳戶的電子郵件地址。

+0

我很多次看到這個問題,很遺憾,我沒有Google管理員帳戶,所以我無法測試它。如果你所做的工作堅持下去:) – DaImTo

相關問題