Skip to content

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

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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