0

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": "REDACTED-320@gsuite-REDACTED.iam.gserviceaccount.com",
  "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 = 'joe@-----.io'
puts authorizer.fetch_access_token!
Hinchy
  • 683
  • 2
  • 7
  • 19

2 Answers2

1

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: "REDACTED-320@gsuite-REDACTED.iam.gserviceaccount.com". 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.

Hinchy
  • 683
  • 2
  • 7
  • 19
  • I've already done this and I'm still getting the same "unauthorized client" error. In fact I've tried every possible combination of suggestions from the web and I still end up with this message. It's incredibly frustrating - Actually - scratch that, now it works. I removed a readonly scope (again). It might be as Jay Lee said. – ShadowScripter Apr 05 '18 at 18:13
  • Glad you got it to work. I agree this was way more challenging than it should have been. The fact that there's about a dozen official documents covering this process doesn't help. – Hinchy Apr 06 '18 at 08:07
0

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

Jay Lee
  • 13,415
  • 3
  • 28
  • 59