Skip to content

Client is unauthorized to retrieve access tokens using this method" w/ Service Account  #2214

@amanets

Description

@amanets

PROBLEM / CAUSE: I am using google-php-api-client to create calendar event, with service account and set the subject, subject email address is my admin account, with out subject this is working but when i am set subject this is not working and given error Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested,
When i am calling throw google API this is working properly
API Calling code is :

define('CALENDAR_ID', <claendar_id>); 

/*********************** Start: Create access Token***********************************/
function base64url_encode($data) {
    return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}

function getJwtAssertion($private_key_file)
{
    $json_file = file_get_contents($private_key_file);
    $info = json_decode($json_file);
    $private_key = $info->{'private_key'};

    //{Base64url encoded JSON header}
    $jwtHeader = base64url_encode(json_encode(array(
        "alg" => "RS256",
        "typ" => "JWT"
    )));
    //{Base64url encoded JSON claim set}
    $now = time();
    $jwtClaim = base64url_encode(json_encode(array(
        "iss" => <serviceaccount>,
        "sub" => <admin_email_address>,
        "scope" => "https://www.googleapis.com/auth/calendar",
        "aud" => "https://www.googleapis.com/oauth2/v4/token",
        "exp" => $now + 3600,
        "iat" => $now
    )));

    $data = $jwtHeader.".".$jwtClaim;

    // Signature
    $Sig = '';
    openssl_sign($data,$Sig,$private_key,'SHA256');
    $jwtSign = base64url_encode($Sig);
    $jwtAssertion = $data.".".$jwtSign;
    return $jwtAssertion;
}

function getGoogleAccessToken($private_key_file)
{
    $result = [
      'success' => false,
      'message' => '',
      'token' => null
    ];   
    if(!file_exists($private_key_file)){
        $result['message'] = 'Google json key file missing!';
        return $result;
    }
    $jwtAssertion = getJwtAssertion($private_key_file);
    try { 
        $payload = [
            'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
            'assertion' => $jwtAssertion
        ];
        $url = 'https://oauth2.googleapis.com/token';
        $ch = curl_init();      
          curl_setopt($ch, CURLOPT_URL, $url);        
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);        
          curl_setopt($ch, CURLOPT_POST, 1);      
          curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
          curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);    
          $data = json_decode(curl_exec($ch), true);
        $http_code = curl_getinfo($ch,CURLINFO_HTTP_CODE);
        if($http_code != 200){
          $result['message'] = 'Error : Failed to access token';
          
        } else {
            $result['token'] = $data['access_token'];
            $result['success'] = true;
        }
    } catch (RequestException $e) {
          $result['message'] = $e->getMessage();
    }
    return $result;
}
$KEY_FILE_LOCATION = __DIR__.'/key_file.json';
$googleToken = getGoogleAccessToken($KEY_FILE_LOCATION);
/*********************** End Create access Token***********************************/
if(isset($googleToken['token'])){
    $access_token = $googleToken['token'];
    getCalendarDetails($access_token); 
}
function getCalendarDetails($access_token) {
    $url_events = 'https://www.googleapis.com/calendar/v3/calendars/claendar_id';
    $ch = curl_init();  
    curl_setopt($ch, CURLOPT_URL, $url_events);        
    // curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    // curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET"); 
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);   
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer '. $access_token, 'Content-Type: application/json')); 

    $data = curl_exec($ch);
    $http_code = curl_getinfo($ch,CURLINFO_HTTP_CODE);

    echo "<pre>";
    print_r($data);
    die();
}

But i am set the subject with Google php client is not working

My code is :

require_once 'vendor/autoload.php';
putenv('GOOGLE_APPLICATION_CREDENTIALS='.__DIR__.'/clanedar_key.json');

$calendarId = <calendar_id>;

$client = new Google_Client();

// use the application default credentials
$client->useApplicationDefaultCredentials();
$client->setSubject("admin_gmail_account");

$client->addScope([Google_Service_Calendar::CALENDAR_EVENTS, Google_Service_Calendar::CALENDAR]);

$service = new Google_Service_Calendar($client);

$optParams = array(
    'maxResults' => 10,
    'orderBy' => 'startTime',
    'singleEvents' => true,
    'timeMin' => date('c', strtotime('2022-01-28 9:00am -1 minute')),
    'timeMax' => date('c', strtotime('2022-02-28 10:00am +1 minute')),
);
$results = $service->events->listEvents($calendarId, $optParams);

foreach ($results->getItems() as $event) {
    $start = $event->start->dateTime;
    $start = !$start ? $event->start->date : $start;
    $end = $event->end->dateTime;
    printf($event->getSummary() . "<br>" . $start . "<br>" .$end. "<br>". $event->hangoutLink ."<br><br>");
} 

Seen Error :
Fatal error: Uncaught Google\Service\Exception: { "error": "unauthorized_client", "error_description": "Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested." } in /var/www/html/google-api-php-client-main/src/Http/REST.php:128 Stack trace: #0 /var/www/html/google-api-php-client-main/src/Http/REST.php(103): Google\Http\REST::decodeHttpResponse() googleapis/google-api-dotnet-client#1 [internal function]: Google\Http\REST::doExecute() googleapis/google-api-dotnet-client#2 /var/www/html/google-api-php-client-main/src/Task/Runner.php(182): call_user_func_array() googleapis/google-api-dotnet-client#3 /var/www/html/google-api-php-client-main/src/Http/REST.php(66): Google\Task\Runner->run() googleapis/google-api-dotnet-client#4 /var/www/html/google-api-php-client-main/src/Client.php(918): Google\Http\REST::execute() googleapis/google-api-dotnet-client#5 /var/www/html/google-api-php-client-main/src/Service/Resource.php(238): Google\Client->execute() googleapis/google-api-dotnet-client#6 /var/www/html/google-api-php-client-main/vendor/google/apiclient-services/src/Calendar/Resource/Events.php(271): Google\Service\Resource->call() googleapis/google-api-dotnet-client#7 /var/www/html/google-api-php-c in /var/www/html/google-api-php-client-main/src/Http/REST.php on line 128

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority: p3Desirable enhancement or fix. May not be included in next release.type: questionRequest for information or clarification. Not an issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions