Access_denied when accessing the Gmail API with scope https://mail.google.com/
I am trying to read / write emails / folders inside Gmail inboxes using Gmail REST API. By adding the following Google Authentication Scopes, emails can be read from the Gmail REST API without any problem:
https://apps-apis.google.com/a/feeds/compliance/audit/ , https://www.googleapis.com/auth/admin.directory.user.readonly , https://www.googleapis.com /auth/gmail.readonly https://www.googleapis.com/auth/admin.directory.group.member.readonly , https://www.googleapis.com/auth/admin.directory.group.readonly
Note. The https://www.googleapis.com/auth/gmail.readonly setting correctly allows reading from mailboxes.
However, I also need to delete emails. So according to the documentation at https://developers.google.com/gmail/api/auth/scopes?hl=ja you just need to include https://mail.google.com/ instead of https: //www.googleapis .com / auth / gmail.readonly . When adding the following authentication scopes:
https://apps-apis.google.com/a/feeds/compliance/audit/ , https://www.googleapis.com/auth/admin.directory.user.readonly , https://mail.google.com / , https://www.googleapis.com/auth/admin.directory.group.member.readonly , https://www.googleapis.com/auth/admin.directory.group.readonly
... the displayed error looks like this:
2015-07-27 10:27:59 i.c.s.a.cv [DEBUG] failed get labels for user
com.google.api.client.auth.oauth2.TokenResponseException: 403 Forbidden
{
"error" : "access_denied",
"error_description" : "Requested client not authorized."
}
Surely this is wrong on Google's part? What am I missing? Incorrect documentation? What scope of authority do you need to add?
I am interacting with the Google API Java client library. See: https://developers.google.com/api-client-library/java/google-api-java-client/reference/1.20.0/overview-summary
The delete request looks like this:
public void deleteMessages(Queue<String> messages, GoogleUserAdapter user) throws Exception {
Gmail gmail = getService(user);
JsonBatchCallback<Void> voidCallBack = new JsonBatchCallback<Void>() {
@Override
public void onSuccess(Void t, HttpHeaders responseHeaders) throws IOException {
logger.debug("delete success");
}
@Override
public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) throws IOException {
logger.debug("failed to delete message:"+e.getMessage());
}
};
while (!messages.isEmpty()) {
if (Thread.currentThread().isInterrupted())
throw new InterruptedException();
BatchRequest batch = gmail.batch();
for (int i = 0; i < MAX_REQUESTS; i++) {
if (messages.isEmpty() || Thread.currentThread().isInterrupted())
break;
gmail.users().messages().delete(user.getId(), messages.poll()).queue(batch, voidCallBack);
}
batch.execute();
}
}
Credentials are created as follows:
private GoogleCredential getCredentials(JsonFactory jsonFactory, HttpTransport httpTransport, String impersonateAccount) throws Exception {
Preconditions.checkNotNull(Strings.emptyToNull(impersonateAccount), "Google impersonate account is null");
Preconditions.checkNotNull(Strings.emptyToNull(connection.getServiceAccountId()), "Service Account Email address is null");
Preconditions.checkNotNull(connection.getServiceAccountPrivateKey(), "Service Account Private Key is null");
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(connection.getServiceAccountId())
.setServiceAccountScopes(
Arrays.asList(DirectoryScopes.ADMIN_DIRECTORY_USER_READONLY, GmailScopes.MAIL_GOOGLE_COM,
"https://apps-apis.google.com/a/feeds/compliance/audit/",
DirectoryScopes.ADMIN_DIRECTORY_GROUP_MEMBER_READONLY,
DirectoryScopes.ADMIN_DIRECTORY_GROUP_READONLY))
.setServiceAccountUser(impersonateAccount)
.setServiceAccountPrivateKey(connection.getServiceAccountPrivateKey().getPrivateKey())
.build();
setHttpTimeout(credential);
return credential;
}
The exact error that occurs when uninstalling:
failed to delete message:Insufficient Permission
Jamie
source to share
Access denied, caused by a typo in the GmailScopes.MAIL_GOOGLE_COM constant as defined by the Google Java Client API.
The constant returns " https://mail.google.com ", not " https://mail.google.com/ " (as it should). Omitting the backslash at the end of the line will result in access denied.
So, in the above example, the following service areas should be set:
https://apps-apis.google.com/a/feeds/compliance/audit/ "," https://mail.google.com/ ", DirectoryScopes.ADMIN_DIRECTORY_GROUP_MEMBER_READONLY, DirectoryScopes.ADMIN_DIRECTORY_USER_READONLY, Directory_Scopes.ADMINLY
(note: hard coded value https://mail.google.com/ ")
The following line should be added to the Control API Client Access page in Google Apps:
https://apps-apis.google.com/a/feeds/compliance/audit/ , https://www.googleapis.com/auth/admin.directory.user.readonly , https://mail.google.com / , https://www.googleapis.com/auth/admin.directory.group.member.readonly , https://www.googleapis.com/auth/admin.directory.group.readonly
I hope this helps someone else!
source to share