google-api-java-client-services
google-api-java-client-services copied to clipboard
Directory API: Not Authorized to access this resource/api
Hi,
I am trying to list users within my gSuite domain from a gke cluster using a service account. I have done the following to test the service account with the google-api-services-admin-directory
api:
Within my Google Cloud Account I have enabled the Admin SDK. I then created a domain-wide service account in the project as described here https://developers.google.com/admin-sdk/directory/v1/guides/delegation, then downloaded the JSON key file and gave it authorization to the following scopes in the Admin Console:
https://www.googleapis.com/auth/admin.directory.group.member.readonly
https://www.googleapis.com/auth/admin.directory.group.readonly
https://www.googleapis.com/auth/admin.directory.user.readonly
https://www.googleapis.com/auth/admin.directory.user.security
I then setup a very basic Java application to test listing groups:
Test.java
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.directory.Directory;
import com.google.api.services.directory.DirectoryScopes;
import com.google.api.services.directory.model.Groups;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.List;
public class Test {
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private static final List<String> SCOPES = new ArrayList<>();
private static Credential getCredentials(NetHttpTransport netHttpTransport) throws IOException {
SCOPES.add(DirectoryScopes.ADMIN_DIRECTORY_USER_READONLY);
SCOPES.add(DirectoryScopes.ADMIN_DIRECTORY_GROUP_READONLY);
SCOPES.add(DirectoryScopes.ADMIN_DIRECTORY_USER_SECURITY);
GoogleCredential credential = GoogleCredential.getApplicationDefault(netHttpTransport, JSON_FACTORY).createScoped(SCOPES);
return credential;
}
public static void main(String... args) throws IOException, GeneralSecurityException {
final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
Directory directory = new Directory.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT)).setApplicationName("test").build();
Directory.Groups.List list = directory.groups().list();
list.setDomain("mydomain.com");
Groups users = list.execute();
users.getGroups().forEach(g -> System.out.println(g.getName()));
}
}
pom.xml
<dependencies>
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-admin-directory</artifactId>
<version>directory_v1-rev20191003-1.30.8</version>
</dependency>
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>1.30.8</version>
</dependency>
</dependencies>
Before running the java file I set the GOOGLE_APPLICATION_CREDENTIALS environment variable to point to my json service account file.
When running this no matter whether I am trying to access users or groups I keep getting the following error message from the API:
{
"code" : 403,
"errors" : [ {
"domain" : "global",
"message" : "Not Authorized to access this resource/api",
"reason" : "forbidden"
} ],
"message" : "Not Authorized to access this resource/api"
}
Stack trace:
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:150)
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:444)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1108)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:542)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:475)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:592)
I believe this issue might be related to the issue mentioned in the google-api-nodejs-client
project:
https://github.com/googleapis/google-api-nodejs-client/issues/1884
Adding the scope https://www.googleapis.com/auth/admin.directory.user.security
does not resolve the problem.
Regards
The same for me. I created service account with full access. And added all necessary scopes.
https://www.googleapis.com/auth/admin.directory.user
https://www.googleapis.com/auth/admin.directory.user.security
and etc.
But can't get any user. Get this error every time Directory API: Not Authorized to access this resource/api
I've solved this problem by setting the serviceAccountUser to my admin email address to impersonate it.
val googleServiceAccountKey =
javaClass.classLoader.getResourceAsStream("google_service_account_key.json")!!
val credential =
GoogleCredential.fromStream(googleServiceAccountKey)
.createScoped(
listOf(
DirectoryScopes.ADMIN_DIRECTORY_USER,
DirectoryScopes.CLOUD_PLATFORM
)
)
FieldUtils.writeDeclaredField(credential, "serviceAccountUser", "ADMIN_EMAIL_ADDRSES", true)