1

I'm trying to retrieve/update Google group membership in a background process with a service account but getting this error when executing query. How to add these permissions to the service account?

Google.GoogleApiException: 'Google.Apis.Requests.RequestError
Not Authorized to access this resource/api [403]
Errors [
    Message[Not Authorized to access this resource/api] Location[ - ] Reason[forbidden] Domain[global]
]
'

C# code:

using FileStream fileStream = File.OpenRead(@"key.json");
GoogleCredential googleCredential = GoogleCredential.FromStream(fileStream)
    .CreateScoped("https://www.googleapis.com/auth/admin.directory.group.member");
BaseClientService.Initializer initializer = new()
{
    HttpClientInitializer = googleCredential,
    ApplicationName = "My App",
};
DirectoryService service = new(initializer);
MembersResource.ListRequest listRequest = service.Members.List("my-group@example.com");
Members members = await listRequest.ExecuteAsync();

2 Answers2

0

It seems that you have to use setServiceAccountUser, which is not supported in JSON based credentials. You could build it like this:

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);
}

Reference:

NightEye
  • 10,634
  • 2
  • 5
  • 24
0

Thank you, I've changed these lines and now it works!

GoogleCredential googleCredential = GoogleCredential.FromStream(fileStream)
    .CreateScoped("https://www.googleapis.com/auth/admin.directory.group.member")
    .CreateWithUser("my-user@example.com");