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

1

15

I have a problem just using an example of actual version of PHP api, and using the "service-account.php" file of examples folder.

the original is for show the "Books API", and with my personal credentials configuration it works well, but in my xcase I need to access by directory.groups.get service to have the list of members accounts of a google groups mail list, so I change the original code in this:

<?php

session_start();
include_once "templates/base.php";

/************************************************
  Make an API request authenticated with a service
  account.
 ************************************************/
require_once realpath(dirname(__FILE__) . '/../autoload.php');

/************************************************
 ************************************************/

// MY ACCOUNT DATA HERE
$client_id = 'xxx';
$service_account_name = 'xxx'; //Email Address 
$key_file_location = 'xxx.p12'; //key.p12
$groupKey = 'xxx';

echo pageHeader("My Service Account Access");
if ($client_id == '<YOUR_CLIENT_ID>'
    || !strlen($service_account_name)
    || !strlen($key_file_location)) {
  echo missingServiceAccountDetailsWarning();
}

$client = new Google_Client();
$client->setApplicationName("Client_Library_Examples");
//$service = new Google_Service_Books($client); //ORIGINAL
$service = new Google_Service_Directory($client);

/************************************************
 ************************************************/
if (isset($_SESSION['service_token'])) {
  $client->setAccessToken($_SESSION['service_token']);
}
$authArray = array(
                'https://www.googleapis.com/auth/admin.directory.group',
                'https://www.googleapis.com/auth/admin.directory.group.readonly',
                'https://www.googleapis.com/auth/admin.directory.group.member',
                'https://www.googleapis.com/auth/admin.directory.group.member.readonly'
);
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
    $service_account_name,
    $authArray, //array('https://www.googleapis.com/auth/books'), //ORIGINAL
    $key
);
$client->setAssertionCredentials($cred);
if($client->getAuth()->isAccessTokenExpired()) {
  $client->getAuth()->refreshTokenWithAssertion($cred);
}
$_SESSION['service_token'] = $client->getAccessToken();


/************************************************
 ************************************************/
//$optParams = array('filter' => 'free-ebooks'); //ORIGINAL
$optParams = array('fields' => 'id');
//$results = $service->volumes->listVolumes('Henry David Thoreau', $optParams); //ORIGINAL
$results = $service->groups->get($groupKey, $optParams);
echo "<h3>Results Of Call:</h3>";
foreach ($results as $item) {
  //echo $item['volumeInfo']['title'], "<br /> \n"; //ORIGINAL
    echo "<pre>".print_r ($item, true)."</pre>";
}

echo pageFooter(__FILE__);

whatever I do, providing authorization for API SDK, and using file and credentials just created in API Credentials panel of the console's developer, I receive alwais the 403 error.

Here's the error stack:

#0 /var/www/html/google_local/google-api-php-client-master/src/Google/Http/REST.php(41): 
Google_Http_REST::decodeHttpResponse(Object(Google_Http_Request)) 
#1 /var/www/html/google_local/google-api-php-client-master/src/Google/Client.php(546): 
Google_Http_REST::execute(Object(Google_Client), Object(Google_Http_Request)) 
#2 /var/www/html/google_local/google-api-php-client-master/src/Google/Service/Resource.php(190): 
Google_Client->execute(Object(Google_Http_Request)) 
#3 /var/www/html/google_local/google-api-php-client-master/src/Google/Service/Directory.php(1494): 
Google_Service_Resource->call('get', Array, 'Google_Service_...') 
#4 /var/www/html/google_local/googl in /var/www/html/google_local/google-api-php-client-master/src/Google/Http/REST.php on line 76

Any suggestions?

Thanks, Roberto

Highhanded answered 16/10, 2014 at 16:14 Comment(9)
Do you have the right permissions on your account to execute that method? I would recommend you try their console here: developers.google.com/apis-explorer/#p/admin/directory_v1/… -- that way, you can see a verbose and easy to understand explanation of why you're getting a 403.Konyn
hi, thanks for the answer! yes, the console give me 200 OK response in the page you indicate, and I receve also a 200 response in the test for members (the data that I want obtain by programming way) in developers.google.com/apis-explorer/#p/admin/directory_v1/…Highhanded
Roberto, when you OAuth approve the Google console, check the scopes that it's asking permission for. They're likely visible in the URI. Ask for those same scopes in your array.Konyn
yes, I think that the scope is ok, in the code posted above I put everything in $authArray array for that. other suggestions?Highhanded
Are you certain that your google account is marked as an admin for your domain/group?Konyn
I understand now... ok the domain admin will create credentials for a project of his console, and I just need to add these datas in the configuration of my script, without be also my a domain admin. thanks, I will update about the success or not of my script!Highhanded
not working anyway.. :( it works with Book API, not with Admin SDK API...Highhanded
Ask your domain admin to try the console with their credentials.Konyn
yes, I tryied with a new project created from him and associated also to me (I'm now the co-owner of the project), I create in his project the new Client ID, and the result doesn't changeHighhanded
A
37

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 = "[email protected]";
Amu answered 20/10, 2014 at 15:26 Comment(6)
it works!! yes, following exactly this way, the piece of code posted works perfectly, I can read all datas! thanks a lot!Highhanded
Life saver! Thank you! In C# you'd do it by making a copy of the GoogleCredential object: googleCredential = googleCredential.CreateWithUser("[email protected]");Bernina
I could finally finish my two days of authorization failure. Thank you so much.Southernly
@Elliptica You can look at this answer for a Python solutionHeavyhearted
100+ likes to this! Great answer.Otterburn
Thanks for the post. qq, does the above domain admin mean SuperAdmin privilege?Pedicab

© 2022 - 2024 — McMap. All rights reserved.