问题描述
目标是在G-Suite平台中建立一个服务帐户,应用程序可以使用该帐户执行操作而不会提示用户进行身份验证.
The goal is to establish a Service Account in the G-Suite platform that an application can use to perform actions without prompting users to authenticate.
我们遇到的问题与以下帖子非常相似,但略有不同.
We are experiencing issues very similar to the following postings, but slightly differently.
- Google Admin SDK authentication with service account
- How to authorise a service account to access the Google Admin API
只要我们遵循模拟"流程,一切就可以正常进行.通过模拟,授权规则将遵循被模拟的用户.理想情况下,我们希望相应地对服务帐户进行范围设置,而不是模拟用户.我们不断收到403.
As long as we follow the 'impersonation" flow, things work. With impersonation, the authorization rules follow the user being impersonated. Ideally, we want to SCOPE the service account accordingly and not impersonate a user. When we do this, we constantly receive a 403.
我们已尽力按照此处的说明进行操作:
We've tried our best to follow the instructions here:
- https://developers.google.com/admin-sdk /directory/v1/guides/delegation
- https://developers.google.com/identity/protocols /OAuth2ServiceAccount?hl = zh_CN#delegatingauthority
- https: //medium.com/@Skaaptjop/access-gsuite-apis-on-your-domain-using-a-service-account-e2a8dbda287c
- https://developers.google.com/admin-sdk/directory/v1/guides/delegation
- https://developers.google.com/identity/protocols/OAuth2ServiceAccount?hl=en_US#delegatingauthority
- https://medium.com/@Skaaptjop/access-gsuite-apis-on-your-domain-using-a-service-account-e2a8dbda287c
我们的Java代码段与此类似:
Our Java snippet is similar to this:
final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
File file = new File(MdmResource.class.getClassLoader().getResource("myproject.p12").getFile());
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(HTTP_TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId("105601508644514129999")
.setServiceAccountPrivateKeyFromP12File(file)
.setServiceAccountScopes(
Collections.singletonList(DirectoryScopes.ADMIN_DIRECTORY_USER_READONLY))
.setServiceAccountUser("[email protected]") // 403 when this is commented out
.build();
Directory dir = new Directory(HTTP_TRANSPORT, JSON_FACTORY, credential);
Get result = dir.users().get("[email protected]");
User user = result.execute();
System.out.println(user.get("customerId"));
在GCP中,我们以超级管理员身份登录时创建了ServiceAccount.我们启用了域范围委派并生成了密钥(在本示例中为p12类型,并使用相应的文件作为Java应用程序的输入).
In GCP, we created the ServiceAccount while logged in as a superadmin. We enabled Domain-Wide delegation and generated the keys (in this example, the p12 type and used the corresponding file as input into the Java app).
然后,在API库中,我们启用了 Admin SDK .
Then, in the API Library, we enabled Admin SDK.
在Google管理员的安全性/高级"设置下,我们设置了范围.我们使用了105601508644514129999和 https://www.googleapis.com/auth/admin.directory.device.mobile,https://www. googleapis.com/auth/admin.directory.user.readonly,https://www.googleapis.com/auth/admin.directory.user
In the Google Admin, under Security/Advanced settings, we setup the scopes. We used 105601508644514129999 and https://www.googleapis.com/auth/admin.directory.device.mobile,https://www.googleapis.com/auth/admin.directory.user.readonly,https://www.googleapis.com/auth/admin.directory.user
运行Java代码时,当注释掉"setServiceAccountUser"时,我们将看到以下内容(模拟时,只要用户具有正确的权限,就可以正常工作):
When we run the Java code, we see the following when "setServiceAccountUser" is commented out (works fine when impersonating, as long as the user has the right permissions):
{
"code" : 403,
"errors" : [ {
"domain" : "global",
"message" : "Not Authorized to access this resource/api",
"reason" : "forbidden"
} ],
"message" : "Not Authorized to access this resource/api"
}
因此,似乎我们的SA未正确连接到示波器,但是我不知道如何执行此操作.
So, it seems like our SA is not correctly connected to scopes, but I'm out of ideas how to do this.
顺便说一句,105601508644514129999是在SA创建过程中自动生成的OAuth 2.0凭据的SA唯一ID和客户端ID.如下例所示,我们也将SA电子邮件用于"setServiceAccountId",但仍收到403. https://developers.google.com/admin-sdk/directory/v1/guides/delegation .实际上,我认为该示例也与.setServiceAccountScopes有关.
BTW, the 105601508644514129999 is the SA Unique ID and Client ID of the OAuth 2.0 credentials that were automatically generated during the SA creation process. We also used the SA Email for the "setServiceAccountId" as shown in the following example, but still getting 403. https://developers.google.com/admin-sdk/directory/v1/guides/delegation. Actually, I think this example has another issue with .setServiceAccountScopes too.
最后...
<dependency>
<groupId>com.google.auth</groupId>
<artifactId>google-auth-library-oauth2-http</artifactId>
<version>0.20.0</version>
</dependency>
<!-- Used to navigate Google Directory services, like https://developers.google.com/admin-sdk/directory -->
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-admin-directory</artifactId>
<version>directory_v1-rev117-1.25.0</version>
</dependency>
有什么想法吗?
推荐答案
服务帐户不在G Suite域中(即使它们由其中的用户/项目拥有),因此无法被授予对G的管理员访问权限套件域.他们所能做的就是使用Domain-Wide代理模拟域中的用户.
Service accounts are not in the G Suite domain (even if they are owned by a user / project in it) and thus cannot be granted admin access to the G Suite domain. All they can do is impersonate users in the domain with Domain-Wide Delegation.
您可能希望解决的问题是,使用客户端ID和机密授予作为管理员用户的常规OAuth,并确保获得长期的刷新令牌access_type=offline
.这将使您可以在访问令牌过期时刷新访问令牌,并在不撤消您的访问权限的情况下继续以单个管理员用户的身份进行操作.
What you likely want to settle on is granting regular OAuth as an admin user using a client ID and secret and being sure to get a long-lived refresh token access_type=offline
. This will allow you to refresh the access token whenever it expires and continue acting as the single admin user as long as they don't revoke your access.
这篇关于带有模拟服务帐户的Google Admin SDK的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!