Hinchy
Hinchy

Reputation: 683

Another 401 when impersonating super-admin using service account with Admin SDK

I'm attempting to access the Admin SDK Directory API using a service account with domain wide delegation and the REST API. I can obtain a bearer token successfully when not impersonating a user, but with I attepmt to impersonate a user with a "sub" key, I receive a 401, "unauthorized_client" error. From everything I've read online (both in numerous SO answers & elsewhere), this would indicate that I haven't approved the application in my GSuite Admin console, but this is not the case.

Here are the steps I've taken so far.

1) Enable the Admin SDK enter image description here

2) In IAM & Admin area, create a service account with DwD. enter image description here

3) In Apis & Services area, select credentials and create service account key for the service account I just created. enter image description here

4) Download the private key file.

{
  "type": "service_account",
  "project_id": "gsuite-REDACTED",
  "private_key_id": "------3d2e",
  "private_key": "REDACTED",
  "client_email": "[email protected]",
  "client_id": "-----0381",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://accounts.google.com/o/oauth2/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/REDACTED-320%40gsuite-REDACTED.iam.gserviceaccount.com"
}

5) Enable API Access in admin.google.com enter image description here

6) In "Manage API client access" add the Service Account ID and the following scope for the client created in (3) enter image description here

7) Ensure that the user I plan to impersonate is a "super-admin" enter image description here


When I attempt to generate the bearer token I receive a 401 error

{
 "error": "unauthorized_client",
 "error_description": "Client is unauthorized to retrieve access tokens using this method."
}

I've tried using various libraries but always with the same result, so I'm guessing this has something to do with my app configuration rather than my code implementation. Would appreciate any help. For example, here I am using Ruby:

require 'googleauth'

scopes = ['https://www.googleapis.com/auth/admin.directory.user',
                'https://www.googleapis.com/auth/admin.directory.group']

authorizer = Google::Auth::ServiceAccountCredentials.make_creds(
  json_key_io: File.open("gsuite.json"),
  scope: scopes).dup

authorizer.sub = '[email protected]'
puts authorizer.fetch_access_token!

Upvotes: 0

Views: 736

Answers (2)

Hinchy
Hinchy

Reputation: 683

I figured out the problem - it was configuration not code. In Step 6, when I was autorizing the API client, I was entering the "Service account ID", in my case: "[email protected]". Although this appears to work - the correct numerical ID appears (as shown in screenshot) - I was getting 401 errors.

However, when I entered the "client_id" from my private key file, in my case a number ending in 0381, and used the same scope, THEN I could authenticate successfully.

It's frustrating that entering the service account id didn't throw an error., but all's well that ends well.

Upvotes: 1

Jay Lee
Jay Lee

Reputation: 13528

How long have you waited after step 6? Getting access after it's entered into the admin console can sometimes take a few hours.

Upvotes: 0

Related Questions