问题描述
我正在尝试向Drive API发出使用服务帐户冒充用户的请求,但出现了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 中,创建了一个项目>凭据>服务帐户> P12文件;
- 已启用Drive API;
- 启用了域范围内的委派;
- 在> https://console.developers.google.com/iam-admin/iam ,向电子邮件
test@gmail.com
添加了项目>Editor
的权限(示例).
- 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")
行,则能够执行代码,并且在我的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
.
我见过很多有这个问题的帖子,但是没有一个有具体解决方案的帖子.然后,我查看了上面引用的文档,它对G Suite
说了很多遍,然后我意识到可能是这些请求仅适用于G Suite
帐户.我对吗?如果没有,我该如何运作?
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?
推荐答案
是的,服务帐户的域范围委派仅适用于GSuite用户,因为GSuite管理员必须授予服务帐户域范围的权限-请参阅此处的步骤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
考虑使用常规OAuth( https://developers.google.com/identity/protocols/OAuth2WebServer )以从您的gmail帐户授予对您的网络应用的访问权限.
Consider using regular OAuth (https://developers.google.com/identity/protocols/OAuth2WebServer) to grant access to your web app from your gmail account.
这篇关于我是否需要G Suite帐户来发出使用服务帐户模拟用户的请求?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!