Google authentication with PHP

Viewed 844

I am an Windows/Active directory architect with 25 years experience working for a small company. I am trying to develop a way to manage multiple different authentication systems. One of them is the corporate gmail accounts. I need to be able to both read and write to gmail using Google's admin API. I am coding this in PHP, and using mySQL for the database backend. My problem is that I cannot get the php script to connect to Google. It keeps generating the same error:

 PHP Fatal error:  Uncaught Google_Service_Exception: {
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "forbidden",
    "message": "Not Authorized to access this resource/api"
   }
  ],
  "code": 403,
  "message": "Not Authorized to access this resource/api"
 }
}
 in D:\Inetpub\WWWRoot\datasync\src\Google\Http\REST.php:118
Stack trace:
#0 D:\Inetpub\WWWRoot\datasync\src\Google\Http\REST.php(94): Google_Http_REST::decodeHttpResponse(Object(GuzzleHttp\Psr7\Response), Object(GuzzleHttp\Psr7\Request), 'Google_Service_...')
#1 D:\Inetpub\WWWRoot\datasync\src\Google\Task\Runner.php(176): Google_Http_REST::doExecute(Object(GuzzleHttp\Client), Object(GuzzleHttp\Psr7\Request), 'Google_Service_...')
#2 D:\Inetpub\WWWRoot\datasync\src\Google\Http\REST.php(58): Google_Task_Runner->run()
#3 D:\Inetpub\WWWRoot\datasync\src\Google\Client.php(798): Google_Http_REST::execute(Object(GuzzleHttp\Client), Object(GuzzleHttp\Psr7\Request), 'Google_Service_...', Array)
#4 D:\Inetpub\WWWRoot\datasync\src\Google\Service\Resource.ph in D:\Inetpub\WWWRoot\datasync\src\Google\Http\REST.php on line 118

The script is using a service account to connect, and a json credential file. I have insured the service account has access via the admin console/security/Manage API Client Access:

102632896707704106543   View and manage the provisioning of groups on your domain  https://www.googleapis.com/auth/admin.directory.group 
View and manage the provisioning of users on your domain  https://www.googleapis.com/auth/admin.directory.user

I have also insured the service account has been activated with domain wide delegation.

I have already searched all over the web looking for a solution to this.

Here is my test script that is generating the errors:

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

$credentials_file = './redacted.json';

$client = new \Google_Client();
$client->setAuthConfig($credentials_file);

$client->setApplicationName("webadmin");
$client->setSubject("datasync@redacted.iam.gserviceaccount.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);

 echo realpath(dirname(__DIR__)); 

$userKey = 'cperrine@redacted.com';

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

var_dump($results);
?>

I am missing something, but I don't know what. I have been working on this for a week now and I can't seem to get past it. Any insight would be appreciated.

1 Answers

I think you missing user authentication step.

Credentials included in your $credentials_file = './redacted.json'; file authorises request as made by your application or project as named in Google Dev Console. But when you want to create access to someone's data (eg. mails) you need to authenticate user. I suggest to use oauth 2 tech which will allow you to get user access token (whole proccess is little complicated but is very secure and allows you to ask user for different permissions over his/her account).

When you have user access token you can set it in Google_Client (as I saw you are using official Google PHP library) like this

$client -> refreshToken( $refresh_token );

After that any calls to API should be on behalf of user which token belongs to. In my example I used it in Google Analytics

$service = new Google_Service_Analytics( $client );
Related