Google_Service_Directory - (403) Not Authorized to Access This Resource/Api

Google_Service_Directory - (403) Not Authorized to access this resource/api

The root of the problem is that the service account is not an administrator on the domain, so it cannot access the Admin SDK Directory API. Instead, you need to enable domain-wide delegation for your service account, and then have the service account impersonate a domain admin when it makes the request:

$cred = new Google_Auth_AssertionCredentials(
$service_account_name,
$authArray,
$key
);
$cred->sub = "admin@yourdomain.com";

Service account not Authorized to access this resource/api while trying to access directory api using Python

There is a (very vague) clue in Google documentation to the solution:

Note: Only users with access to the Admin APIs can access the Admin
SDK Directory API, therefore your service account needs to impersonate
one of those users to access the Admin SDK Directory API.
Additionally, the user must have logged in at least once and accepted
the G Suite Terms of Service.

The way to achieve the impersonation in Python is by sending a "subject" when authenticating with OAuth2 library. The subject should be a user with an access to the Admin API (He doesn't have to be an admin, User Management Role should be sufficient, at least for my needs).

A working snippet:

import json
from google.oauth2 import service_account
from googleapiclient.discovery import build

SCOPES = ['https://www.googleapis.com/auth/admin.directory.user.readonly']

credentials = service_account.Credentials.from_service_account_file("/path/to/file.json", scopes=SCOPES, subject="admin@yourdomain.com")

Not Authorized to access this resource/api while trying to access directory api

You have to impersonate the service account with an email of a admin of your google domain.

const client = new JWT(
keys.client_email,
undefined,
keys.private_key,
[
"https://www.googleapis.com/auth/admin.directory.group.readonly",
"https://www.googleapis.com/auth/admin.directory.group.member.readonly",
"https://www.googleapis.com/auth/admin.directory.user.readonly"
],
"admin@yourdomain.com"
);

This is mentioned somewhere in the docs in a box, however not really documented anywhere how to implement...

google admin sdk Not Authorized to access this resource/api php

You can create a user through Users: insert. There is a Try it now to test if you have entered correct/valid data.

Here is a sample code from quickstart to help your progress.

<?php
require_once __DIR__ . '/vendor/autoload.php';

define('APPLICATION_NAME', 'Directory API PHP Quickstart');
define('CREDENTIALS_PATH', '~/.credentials/admin-directory_v1-php-quickstart.json');
define('CLIENT_SECRET_PATH', __DIR__ . '/client_secret.json');
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/admin-directory_v1-php-quickstart.json
define('SCOPES', implode(' ', array(
Google_Service_Directory::ADMIN_DIRECTORY_USER_READONLY)
));

if (php_sapi_name() != 'cli') {
throw new Exception('This application must be run on the command line.');
}

/**
* Returns an authorized API client.
* @return Google_Client the authorized client object
*/
function getClient() {
$client = new Google_Client();
$client->setApplicationName(APPLICATION_NAME);
$client->setScopes(SCOPES);
$client->setAuthConfig(CLIENT_SECRET_PATH);
$client->setAccessType('offline');

// Load previously authorized credentials from a file.
$credentialsPath = expandHomeDirectory(CREDENTIALS_PATH);
if (file_exists($credentialsPath)) {
$accessToken = json_decode(file_get_contents($credentialsPath), true);
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
printf("Open the following link in your browser:\n%s\n", $authUrl);
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));

// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);

// Store the credentials to disk.
if(!file_exists(dirname($credentialsPath))) {
mkdir(dirname($credentialsPath), 0700, true);
}
file_put_contents($credentialsPath, json_encode($accessToken));
printf("Credentials saved to %s\n", $credentialsPath);
}
$client->setAccessToken($accessToken);

// Refresh the token if it's expired.
if ($client->isAccessTokenExpired()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
file_put_contents($credentialsPath, json_encode($client->getAccessToken()));
}
return $client;
}

/**
* Expands the home directory alias '~' to the full path.
* @param string $path the path to expand.
* @return string the expanded path.
*/
function expandHomeDirectory($path) {
$homeDirectory = getenv('HOME');
if (empty($homeDirectory)) {
$homeDirectory = getenv('HOMEDRIVE') . getenv('HOMEPATH');
}
return str_replace('~', realpath($homeDirectory), $path);
}

// Get the API client and construct the service object.
$client = getClient();
$service = new Google_Service_Directory($client);

// Print the first 10 users in the domain.
$optParams = array(
'customer' => 'my_customer',
'maxResults' => 10,
'orderBy' => 'email',
);
$results = $service->users->listUsers($optParams);

if (count($results->getUsers()) == 0) {
print "No users found.\n";
} else {
print "Users:\n";
foreach ($results->getUsers() as $user) {
printf("%s (%s)\n", $user->getPrimaryEmail(),
$user->getName()->getFullName());
}
}

For further information about this error, see this SO post.

you need to enable domain-wide delegation for your service
account, and then have the service account impersonate a domain admin
when it makes the request:

Google SDK API - update Workspace user profile data by service account (Not Authorized to access this resource/api)

When using a service account with domain-wide delegation you need to impersonate a user who has the necessary authorization


  • The Directory API method users.update can only be executed by domain admins with the respective role / permissions.
  • See how to make a user an admin.
  • If in doubt, you can test with the [Try this API](Try this API) authorized as 'admin@domain.com' to verify either this user has the necessary permissions.

PHP - Google Admin SDK - Authentication with Service Accounts Not Authorized to access this resource/api

I could solve the problem. I lacked set subject with my user admin on the domain:

$client->setSubject("admin@yourdomain.com");

Result:

$client = new \Google_Client();

$credentials_file = base_path() . '/service-account.json';

if ($credentials_file = $this->checkServiceAccountCredentialsFile($credentials_file)) {
$client->setAuthConfig($credentials_file);
}

$client->setApplicationName("app-name");
$client->setSubject("admin@yourdomain.com");
$client->setScopes([
'https://www.googleapis.com/auth/admin.directory.user',
'https://www.googleapis.com/auth/admin.directory.user.readonly'
]);

$service = new \Google_Service_Directory($client);

$userKey = 'user@domain.com';

$results = $service->users->get($userKey);

var_dump($results);


Related Topics



Leave a reply



Submit