调用 users().list().execute() 时,Google Directory API 返回 Not Authorized [英] Google Directory API returns Not Authorized when call users().list().execute()
问题描述
我需要从我的 google 域中读取用户(和群组)列表.
I need to read the list of users (and groups) from my google domain.
所以我转到了我的 Google API 控制台并启用了 Admin SDK 并创建了一个 服务帐户来调用 Google API.我使用以下谷歌图书馆
So I went to my Google APIs Console and enabled Admin SDK and created a Service Account to call Google APIs. I use the following google libraries
- google-api-services-admin-directory_v1-rev11-1.16.0-rc.jar
- google-api-client-1.16.0-rc.jar
我的代码是
/*
* Global instance of the JSON factory.
*/
final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
/*
Global instance of the HTTP transport.
*/
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
Collection<String> scopeList = new ArrayList<>();
scopeList.add(DirectoryScopes.ADMIN_DIRECTORY_USER);
scopeList.add(DirectoryScopes.ADMIN_DIRECTORY_GROUP);
scopeList.add(DirectoryScopes.ADMIN_DIRECTORY_GROUP_MEMBER);
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId("nnnnnn@developer.gserviceaccount.com")
.setServiceAccountScopes(scopeList)
.setServiceAccountPrivateKeyFromP12File(new File("/Path/To/KeyFile/nnnnn-privatekey.p12"))
// .setServiceAccountUser("admin@mydomain.org")
.build();
Directory admin = new Directory.Builder(httpTransport, JSON_FACTORY, credential)
.setApplicationName("Test")
.setHttpRequestInitializer(credential).build();
Users users = admin.users().list().setDomain("mydomain.org").execute();
我在最后一行收到这个
错误
{
"code" : 403,
"errors" : [ {
"domain" : "global",
"message" : "Not Authorized to access this resource/api",
"reason" : "forbidden"
} ],
"message" : "Not Authorized to access this resource/api"
}
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:145)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:312)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1045)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:410)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:460)
如果我取消注释注释行 (.setServiceAccountUser("admin@mydomain.org")
) 然后我得到一个不同的错误
If I uncomment the commented line (.setServiceAccountUser("admin@mydomain.org")
) then I get a different error
Exception in thread "main" com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request
{
"error" : "access_denied"
}
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:269)
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:858)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:410)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:460)
我的帐户 (admin@mydomain.org) 是超级管理员.我怀疑需要授予服务帐户访问用户 API 范围的权限.但是我找不到可以授予此访问权限的位置.我的 Google CPanel 有一个经典的 UI 模式.而且我在高级工具中没有管理客户端 API 访问"页面.
My account (admin@mydomain.org) is a super administrator. I suspect the Service Account needs to be granted access for the users API scope. But I can not find where I can grant this access. I have a classic UI mode of my Google CPanel. And I don't have "Manage client API access" page in the Advanced tools.
此外,我不确定在 .setApplicationName("Test")
处应该使用什么作为应用程序名称.
Also I'm not sure what I should use as an Application Name at .setApplicationName("Test")
.
感谢您的帮助
推荐答案
Google Directory API 与 Compute Engine 默认服务帐户配合使用,您无需在域范围内设置 Google Drive.唯一的事情:您必须设置 serviceAccountUser,这在基于 JSON 的凭据中不受支持.所以你可以
Google Directory API works with Compute Engine default service account, you do not need to setup Google Drive domain-wide. The only thing: you have to set serviceAccountUser, which is not supported in JSON based credentials. So you can
- 使用 P12 密钥
- 具有解决方法的用户 JSON 凭据:
制作凭证副本:
import static com.google.api.client.googleapis.util.Utils.getDefaultJsonFactory;
import static com.google.api.client.googleapis.util.Utils.getDefaultTransport;
private static final String APPLICATION_NAME = "AnyAppName";
private final List<String> SCOPES = ImmutableList.of(
DirectoryScopes.ADMIN_DIRECTORY_GROUP_MEMBER, DirectoryScopes.ADMIN_DIRECTORY_USER, DirectoryScopes.ADMIN_DIRECTORY_GROUP);
private Directory service;
@PostConstruct
void init() throws GeneralSecurityException, IOException {
GoogleCredential credential;
try (InputStream is = new FileInputStream("./config/client_secret.json")) {
credential = GoogleCredential.fromStream(is);
}
GoogleCredential credentialWithUser = new GoogleCredential.Builder()
.setTransport(getDefaultTransport())
.setJsonFactory(getDefaultJsonFactory())
.setServiceAccountUser("admin@yourdomain.ru") // <--- mail of domain's admin
.setServiceAccountId(credential.getServiceAccountId())
.setServiceAccountScopes(SCOPES)
.setServiceAccountPrivateKey(credential.getServiceAccountPrivateKey())
.setServiceAccountPrivateKeyId(credential.getServiceAccountPrivateKeyId())
.setTokenServerEncodedUrl(credential.getTokenServerEncodedUrl()).build();
service = new Directory.Builder(getDefaultTransport(), getDefaultJsonFactory(), credentialWithUser).setApplicationName(APPLICATION_NAME).build();
}
public void members() throws IOException {
Members members = service.members().list("groupName@yourdomain.ru").execute();
System.out.println(members);
}
对于我的试用 G Suite 帐户,它有效!
这篇关于调用 users().list().execute() 时,Google Directory API 返回 Not Authorized的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!