Reputation: 764
I am trying to do Domain-Wide Delegation of Authority between my Application Service Account and my organization (on admin.google.com). I followed this guide, about three times, and I cannot know where I miss, it doesn't work. My application is not able to do personification of an user inside the organization.
The response of the API says that:
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)
Here is my unique code, for test:
String emailAddress = "[email protected]";
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("[email protected]") // 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());
}
}
}
If I comment the line marked (setServiceAccountUser("[email protected]")
), the application works, but I want to do the personification of this user test
. That is the intention of this guide provided, to grant access to all users inside mydomain.com.br
.
In the Delegate domain-wide authority to your service account
section of the guide of Google, as mentioned, I followed all the steps, with attention on step number 6
: To add the scope on admin.google.com
under the Security
section.
(google admin configuration for the app)
Upvotes: 1
Views: 531
Reputation: 5519
You have authorized the client id for 1 Drive scope :
https://www.googleapis.com/auth/drive
This scope is stored in Java under the constant DriveScopes.DRIVE
.
But when you create the credential in your code you ask for 4 scopes :
scopes.add(DriveScopes.DRIVE);
scopes.add(DriveScopes.DRIVE_APPDATA);
scopes.add(DriveScopes.DRIVE_APPS_READONLY);
scopes.add(DriveScopes.DRIVE_FILE);
I agree that since DriveScopes.DRIVE
is a scope that includes the other scopes in Drive, it would seem normal that getting an authorization for DriveScopes.DRIVE
would imply that you get the authorization for all the other Drive scopes.
However it is not the case, and you must specify in the Security
section all the scopes that you plan to use. In your case that would be :
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
But since all those scopes are already included in https://www.googleapis.com/auth/drive
you can also simply remove the other scopes from the Java code. That's what I would do :
...
List scopes = new ArrayList();
scopes.add(DriveScopes.DRIVE);
//No other scope
GoogleCredential credential = new GoogleCredential.Builder()
...
Upvotes: 3