google oauth2 使用 user@gmail.com 模拟服务帐户
google oauth2 impersonate service account with user@gmail.com
我想访问一些 google api 服务:
- GDrive API
- 联系API
- 人数API
我正在为 oauth2 模拟服务帐户流程而苦苦挣扎(你知道那个:Google Oauth v2 - service account description。对于模拟,你需要在 google 应用程序控制台中应用 "Delegating domain-wide authority" ,下载相应的 pk12 文件并在 google 控制台项目中激活 api。
目前我总是得到:
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 oauthsample.GDriveAPI.<init>(GDriveAPI.java:50)
at oauthsample.GDriveAPI.main(GDriveAPI.java:85)
这是我的代码:
HttpTransport httpTransport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
Set<String> scopes = new HashSet<String>();
scopes.add("https://www.google.com/m8/feeds");
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId("myserviceuser@xxxxxx.iam.account.com")
.setServiceAccountPrivateKeyFromP12File(new File("somep12key.p12"))
.setServiceAccountScopes(scopes)
.setServiceAccountUser("my_user_name@gmail.com")
.build();
credential.refreshToken();
ContactsService service = new ContactsService("MYAPP");
service.getRequestFactory().setHeader("User-Agent", "MYAPP");
service.setHeader("GData-Version", "3.0");
service.setOAuth2Credentials(credential);
URL feedUrl = new URL("https://www.google.com/m8/feeds/contacts/default/full");
ContactFeed resultFeed = service.getFeed(feedUrl, ContactFeed.class);
我还通过 Whosebug 进行了大量搜索(无法列出所有参考资料并检查了响应和解决方案)。但是有一个问题从来没有得到明确的回答——googles 文档和所有 Whosebug 帖子中也没有:
- 是否真的可以用普通用户@gmail.com 模拟服务帐户(我的意思是普通 gmail 帐户无法访问第 [=48 章中提到的管理控制台) =] 并且没有自己的域 )?
有人说是,有人说不是。那么什么是绝对真理?
据我阅读 google 文档时的理解:服务帐户只能在您负责自己的域时模拟用户,并且您需要有一个 google 工作帐户你自己的域注册。然后您就可以访问管理控制台并授予对服务帐户的访问权限。
感谢您的耐心等待并花时间回答。
此致
马特
简短的回答是否定的,不可能模拟@gmail.com 帐户的服务帐户。关键原因是,虽然服务帐户 OAuth 流程不涉及授权屏幕,但最终还是有人会说 "I authorize this application to impersonate this user."
对于 Google Apps 域,此人是域管理员,他有权为域中的所有用户批准应用程序。对于@gmail.com 帐户,没有其他权限可以代表您批准此操作。而且,如果您无论如何都必须请求用户授权,那么使用常规的三足式 OAuth 流程来提示用户授权、获取刷新令牌等是有意义的。
现在有一段时间有一个技巧,您可以让@gmail.com 用户通过常规的三足流程,一旦他们批准它,就可以从那时起使用服务帐户流程。然而,这会导致一些奇怪的问题,因此我们禁用了该选项。这可能就是为什么过去对这是否可能存在分歧的原因。
我想访问一些 google api 服务:
- GDrive API
- 联系API
- 人数API
我正在为 oauth2 模拟服务帐户流程而苦苦挣扎(你知道那个:Google Oauth v2 - service account description。对于模拟,你需要在 google 应用程序控制台中应用 "Delegating domain-wide authority" ,下载相应的 pk12 文件并在 google 控制台项目中激活 api。
目前我总是得到:
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 oauthsample.GDriveAPI.<init>(GDriveAPI.java:50)
at oauthsample.GDriveAPI.main(GDriveAPI.java:85)
这是我的代码:
HttpTransport httpTransport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
Set<String> scopes = new HashSet<String>();
scopes.add("https://www.google.com/m8/feeds");
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId("myserviceuser@xxxxxx.iam.account.com")
.setServiceAccountPrivateKeyFromP12File(new File("somep12key.p12"))
.setServiceAccountScopes(scopes)
.setServiceAccountUser("my_user_name@gmail.com")
.build();
credential.refreshToken();
ContactsService service = new ContactsService("MYAPP");
service.getRequestFactory().setHeader("User-Agent", "MYAPP");
service.setHeader("GData-Version", "3.0");
service.setOAuth2Credentials(credential);
URL feedUrl = new URL("https://www.google.com/m8/feeds/contacts/default/full");
ContactFeed resultFeed = service.getFeed(feedUrl, ContactFeed.class);
我还通过 Whosebug 进行了大量搜索(无法列出所有参考资料并检查了响应和解决方案)。但是有一个问题从来没有得到明确的回答——googles 文档和所有 Whosebug 帖子中也没有:
- 是否真的可以用普通用户@gmail.com 模拟服务帐户(我的意思是普通 gmail 帐户无法访问第 [=48 章中提到的管理控制台) =] 并且没有自己的域 )?
有人说是,有人说不是。那么什么是绝对真理?
据我阅读 google 文档时的理解:服务帐户只能在您负责自己的域时模拟用户,并且您需要有一个 google 工作帐户你自己的域注册。然后您就可以访问管理控制台并授予对服务帐户的访问权限。
感谢您的耐心等待并花时间回答。
此致 马特
简短的回答是否定的,不可能模拟@gmail.com 帐户的服务帐户。关键原因是,虽然服务帐户 OAuth 流程不涉及授权屏幕,但最终还是有人会说 "I authorize this application to impersonate this user."
对于 Google Apps 域,此人是域管理员,他有权为域中的所有用户批准应用程序。对于@gmail.com 帐户,没有其他权限可以代表您批准此操作。而且,如果您无论如何都必须请求用户授权,那么使用常规的三足式 OAuth 流程来提示用户授权、获取刷新令牌等是有意义的。
现在有一段时间有一个技巧,您可以让@gmail.com 用户通过常规的三足流程,一旦他们批准它,就可以从那时起使用服务帐户流程。然而,这会导致一些奇怪的问题,因此我们禁用了该选项。这可能就是为什么过去对这是否可能存在分歧的原因。