0

I have a Google Apps domain and I want to retrieve the users via the Google Apps Admin API.

I have taken the following steps:

  • Created a service account (under a project associated with a gmail account)
  • Enabled the Admin SDK API and Drive APIs in that project
  • In the Google Apps domain, authorized the service account for domain-wide access with the OAuth scopes https://www.googleapis.com/auth/admin.directory.user and https://www.googleapis.com/auth/drive
  • In the "Admin > Security > API Reference" pane for the domain, I have enabled API access

I have the following Python code:

  creds = SignedJwtAssertionCredentials(SVC_ACCT_EMAIL, SVC_ACCT_KEY,
      scope='https://www.googleapis.com/auth/admin.directory.user')
  http = httplib2.Http()
  http = creds.authorize(http)
  dirSvc = build('admin', 'directory_v1', http=http)
  users = []
  page_token = None
  params = {
    'domain': MY_DOMAIN, # actually my domain here
  }
  page = dirSvc.users().list(**params).execute()
  users.extend(page['users'])

However, it fails with <HttpError 403 when requesting https://www.googleapis.com/admin/directory/v1/users?domain=MY_DOMAIN&viewType=domain_public&alt=json returned "Not Authorized to access this resource/api">

I am confident that my credentials setup and code is correct, because the following code works to create a folder in Drive:

  creds = SignedJwtAssertionCredentials(SVC_ACCT_EMAIL, SVC_ACCT_KEY,
      scope='https://www.googleapis.com/auth/drive', sub=USER_EMAIL)
  http = httplib2.Http()
  http = creds.authorize(http)
  driveSvc = build('drive', 'v2', http=http)
  body = {
    'title': "Test Folder",
    'mimeType': "application/vnd.google-apps.folder",
  }
  folder = service.files().insert(body = body).execute()

Thus implying that my service account is correctly created, domain-authorized, and that I've managed to associate at least one OAuth scope with it.

Things I have tried:

  • using the admin.directory.user.readonly scope
  • adding a user account e-mail (for an admin account) with sub= when creating the directory service
  • trying view_type = domain_public

I have looked into using customer instead of domain in the query to identify my domain, but I can't find my customerId. Trying to fetch it for a user with user = dirSvc.users().get(userKey = USER_EMAIL).execute() fails with the same 403. Regardless, all my users are in the same domain.

I also haven't tried using OAuth for this request; the quickstart uses OAuth, but I was hoping to use the same public-key based service account identification for all the APIs in the app, and I know it's working correctly for Drive.

Tim Dierks
  • 2,168
  • 15
  • 28

1 Answers1

2

Ah, nothing like asking to trigger solving your problem.

I fixed this, using something I had tried above but which didn't work the first time. I had tried adding "sub=" when building the directory service, but at the time I had not yet discovered the API-enabling checkbox in the Apps Admin console. Now that I've checked the latter, passing an admin user e-mail address in when building the creds fixes this problem.

Tim Dierks
  • 2,168
  • 15
  • 28