执行 Google 应用全域授权
Perform Google Apps Domain-Wide Delegation of Authority
我正在尝试在我的应用程序服务帐户和我的组织(在 admin.google.com 上)之间进行全域授权。我跟着 this 指南,大约三遍,我不知道我错过了什么,它不起作用。我的应用程序无法对组织内的用户进行拟人化。
API 的回复说:
Exception in thread "main" com.google.api.client.auth.oauth2.TokenResponseException: 403 Forbidden
{
"error" : "access_denied",
"error_description" : "Requested client not authorized."
}
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:268)
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:859)
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)
at StorageSample.main(StorageSample.java:156)
这是我的唯一代码,用于测试:
String emailAddress = "zzzzzzzzzzzzz@developer.gserviceaccount.com";
JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
//scopes
List scopes = new ArrayList();
scopes.add(DriveScopes.DRIVE);
scopes.add(DriveScopes.DRIVE_APPDATA);
scopes.add(DriveScopes.DRIVE_APPS_READONLY);
scopes.add(DriveScopes.DRIVE_FILE);
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(emailAddress)
.setServiceAccountPrivateKeyFromP12File(new File("valid_path_to_secrets.p12"))
.setServiceAccountScopes(scopes)
.setServiceAccountUser("test@mydomain.com.br") // HERE THE USER I WANT TO PERSONIFICATE
.build();
Drive drive = new Drive.Builder(httpTransport, JSON_FACTORY, credential).setApplicationName("Test").build();
String myName = drive.about().get().execute().getName();
com.google.api.services.drive.Drive.Files.List files = drive.files().list();
FileList fileList = files.execute();
List<com.google.api.services.drive.model.File> xFiles = fileList.getItems();
System.out.println("here");
for (com.google.api.services.drive.model.File f : xFiles){
System.out.println("DEBUG "+f.getOriginalFilename());
System.out.println(f.getDownloadUrl());
System.out.println(f.getAlternateLink());
System.out.println(f.getOwnerNames().get(0));
System.out.println(f.getFileSize());
}
}
}
如果我注释标记为 (setServiceAccountUser("test@mydomain.com.br")
) 的行,应用程序可以运行,但我想将此用户拟人化 test
。这就是提供本指南的目的,向 mydomain.com.br
.
内的所有用户授予访问权限
在 Google 指南的 Delegate domain-wide authority to your service account
部分,如前所述,我遵循了所有步骤,注意步骤编号 6
:要在 [= 上添加范围18=] 在 Security
部分下。
(google 应用程序的管理配置)
您已授权 1 个驱动器范围的客户端 ID:
https://www.googleapis.com/auth/drive
此范围存储在常量 DriveScopes.DRIVE
下的 Java 中。
但是当您在代码中创建凭据时,您需要 4 个范围:
scopes.add(DriveScopes.DRIVE);
scopes.add(DriveScopes.DRIVE_APPDATA);
scopes.add(DriveScopes.DRIVE_APPS_READONLY);
scopes.add(DriveScopes.DRIVE_FILE);
我同意,由于 DriveScopes.DRIVE
是一个包含云端硬盘中其他范围的范围,因此获得 DriveScopes.DRIVE
的授权意味着您获得所有其他范围的授权似乎很正常驱动范围。
然而情况并非如此,您必须在 Security
部分中指定 all 您计划使用的范围。在你的情况下是:
https://www.googleapis.com/auth/drive
https://www.googleapis.com/auth/drive.appdata
https://www.googleapis.com/auth/drive.apps.readonly
https://www.googleapis.com/auth/drive.file
但是由于所有这些范围都已包含在 https://www.googleapis.com/auth/drive
中,您也可以简单地从 Java 代码中删除其他范围。这就是我要做的:
...
List scopes = new ArrayList();
scopes.add(DriveScopes.DRIVE);
//No other scope
GoogleCredential credential = new GoogleCredential.Builder()
...
我正在尝试在我的应用程序服务帐户和我的组织(在 admin.google.com 上)之间进行全域授权。我跟着 this 指南,大约三遍,我不知道我错过了什么,它不起作用。我的应用程序无法对组织内的用户进行拟人化。
API 的回复说:
Exception in thread "main" com.google.api.client.auth.oauth2.TokenResponseException: 403 Forbidden
{
"error" : "access_denied",
"error_description" : "Requested client not authorized."
}
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:268)
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:859)
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)
at StorageSample.main(StorageSample.java:156)
这是我的唯一代码,用于测试:
String emailAddress = "zzzzzzzzzzzzz@developer.gserviceaccount.com";
JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
//scopes
List scopes = new ArrayList();
scopes.add(DriveScopes.DRIVE);
scopes.add(DriveScopes.DRIVE_APPDATA);
scopes.add(DriveScopes.DRIVE_APPS_READONLY);
scopes.add(DriveScopes.DRIVE_FILE);
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(emailAddress)
.setServiceAccountPrivateKeyFromP12File(new File("valid_path_to_secrets.p12"))
.setServiceAccountScopes(scopes)
.setServiceAccountUser("test@mydomain.com.br") // HERE THE USER I WANT TO PERSONIFICATE
.build();
Drive drive = new Drive.Builder(httpTransport, JSON_FACTORY, credential).setApplicationName("Test").build();
String myName = drive.about().get().execute().getName();
com.google.api.services.drive.Drive.Files.List files = drive.files().list();
FileList fileList = files.execute();
List<com.google.api.services.drive.model.File> xFiles = fileList.getItems();
System.out.println("here");
for (com.google.api.services.drive.model.File f : xFiles){
System.out.println("DEBUG "+f.getOriginalFilename());
System.out.println(f.getDownloadUrl());
System.out.println(f.getAlternateLink());
System.out.println(f.getOwnerNames().get(0));
System.out.println(f.getFileSize());
}
}
}
如果我注释标记为 (setServiceAccountUser("test@mydomain.com.br")
) 的行,应用程序可以运行,但我想将此用户拟人化 test
。这就是提供本指南的目的,向 mydomain.com.br
.
在 Google 指南的 Delegate domain-wide authority to your service account
部分,如前所述,我遵循了所有步骤,注意步骤编号 6
:要在 [= 上添加范围18=] 在 Security
部分下。
(google 应用程序的管理配置)
您已授权 1 个驱动器范围的客户端 ID:
https://www.googleapis.com/auth/drive
此范围存储在常量 DriveScopes.DRIVE
下的 Java 中。
但是当您在代码中创建凭据时,您需要 4 个范围:
scopes.add(DriveScopes.DRIVE);
scopes.add(DriveScopes.DRIVE_APPDATA);
scopes.add(DriveScopes.DRIVE_APPS_READONLY);
scopes.add(DriveScopes.DRIVE_FILE);
我同意,由于 DriveScopes.DRIVE
是一个包含云端硬盘中其他范围的范围,因此获得 DriveScopes.DRIVE
的授权意味着您获得所有其他范围的授权似乎很正常驱动范围。
然而情况并非如此,您必须在 Security
部分中指定 all 您计划使用的范围。在你的情况下是:
https://www.googleapis.com/auth/drive
https://www.googleapis.com/auth/drive.appdata
https://www.googleapis.com/auth/drive.apps.readonly
https://www.googleapis.com/auth/drive.file
但是由于所有这些范围都已包含在 https://www.googleapis.com/auth/drive
中,您也可以简单地从 Java 代码中删除其他范围。这就是我要做的:
...
List scopes = new ArrayList();
scopes.add(DriveScopes.DRIVE);
//No other scope
GoogleCredential credential = new GoogleCredential.Builder()
...