問題描述
我正在嘗試使用服務(wù)帳戶向 Drive API 發(fā)出模擬用戶的請(qǐng)求,但我收到 TokenResponseException: 401 Unauthorized
異常.
I'm trying to make requests to Drive API impersonating an user using a service account but I'm getting a TokenResponseException: 401 Unauthorized
exception.
我已遵循 https://developers.google.com/identity 中的描述/protocols/OAuth2ServiceAccount:
- 在 https://console.developers.google.com 中,創(chuàng)建了一個(gè) Project > Credentials >服務(wù)帳號(hào) > P12 文件;
- 啟用 Drive API;
- 啟用域范圍的委派;
- 在 https://console.developers.google.com/iam-admin/iam,添加了 Project >
Editor
權(quán)限以通過電子郵件發(fā)送test@gmail.com
(示例).
- In https://console.developers.google.com, created a Project > Credentials > Service account > P12 file;
- Enabled Drive API;
- Enabled domain-wide delegation;
- In https://console.developers.google.com/iam-admin/iam, added Project >
Editor
permission to emailtest@gmail.com
(example).
然后,在我的代碼中:
File p12 = new File("p12FileFromDevelopersConsole.p12");
HttpTransport transport = GoogleNetHttpTransport.newTrustedTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
GoogleCredential c = new GoogleCredential.Builder()
.setTransport(transport)
.setJsonFactory(jsonFactory)
.setServiceAccountId("MY_ID@MY-ID.iam.gserviceaccount.com")
.setServiceAccountUser("test@gmail.com")
.setServiceAccountScopes(Arrays.asList(DriveScopes.DRIVE, DriveScopes.DRIVE_APPDATA, DriveScopes.DRIVE_FILE, DriveScopes.DRIVE_METADATA_READONLY))
.setServiceAccountPrivateKeyFromP12File(p12)
.build();
List<com.google.api.services.drive.model.File> files = drive.files()
.list()
.setSpaces("drive")
.setFields("nextPageToken, files(id, name, webViewLink)")
.setPageSize(10)
.execute() // < --- exception is thrown here
.getFiles();
for(com.google.api.services.drive.model.File f : files) {
System.out.println(f.getName());
}
堆棧跟蹤是:
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 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)
我注意到,如果我注釋掉 .setServiceAccountUser("test@gmail.com")
行,我可以執(zhí)行代碼并在我的 中打印Getting started"System.out.println
.
I could note that if I comment out the line .setServiceAccountUser("test@gmail.com")
, I am able to execute code and it prints "Getting started" in my System.out.println
.
我看過很多關(guān)于這個(gè)問題的帖子,但沒有一個(gè)具體的解決方案.然后,我查看了上面引用的文檔,其中多次提到 G Suite
,然后我意識(shí)到這些請(qǐng)求可能只適用于 G Suite
帳戶.我對(duì)嗎?如果沒有,我怎樣才能讓它工作?
I've seen many posts with this problem but none with a concrete solution. Then, I looked at documentation referenced above and it says many times about G Suite
and then I realize it could be that these requests only work with a G Suite
account. Am I right? If not, how can I make it work?
推薦答案
是的,服務(wù)帳戶的域范圍委派僅適用于 GSuite 用戶,因?yàn)?GSuite 管理員必須授予服務(wù)帳戶域范圍的權(quán)限——請(qǐng)參見此處的步驟 4:https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority
Yes, domain-wide delegation for service accounts is only for GSuite users because GSuite admins must grant service accounts domain-wide authority -- see Step 4 here: https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority
考慮使用常規(guī) OAuth (https://developers.google.com/identity/protocols/OAuth2WebServer) 以從您的 gmail 帳戶授予對(duì) Web 應(yīng)用程序的訪問權(quán)限.
Consider using regular OAuth (https://developers.google.com/identity/protocols/OAuth2WebServer) to grant access to your web app from your gmail account.
這篇關(guān)于我是否需要 G Suite 帳戶才能使用服務(wù)帳戶冒充用戶?的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!