Google_Service_Directory - (403) 无权访问此资源/api

Posted

技术标签:

【中文标题】Google_Service_Directory - (403) 无权访问此资源/api【英文标题】:Google_Service_Directory - (403) Not Authorized to access this resource/api 【发布时间】:2014-12-12 02:28:53 【问题描述】:

我只是使用实际版本的 php api 示例,并使用示例文件夹的“service-account.php”文件时遇到问题。

原件用于显示“Books API”,并且使用我的个人凭据配置它运行良好,但在我的 xcase 中,我需要通过 directory.groups.get 服务访问以获得 google 组的成员帐户列表邮件列表,所以我在此更改原始代码:

<?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__);

无论我做什么,为 API SDK 提供授权,并使用刚刚在控制台开发人员的 API 凭据面板中创建的文件和凭据,我都会收到 403 错误。

这是错误堆栈:

#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

有什么建议吗?

谢谢, 罗伯托

【问题讨论】:

您的帐户是否具有执行该方法的正确权限?我建议您在这里尝试他们的控制台:developers.google.com/apis-explorer/#p/admin/directory_v1/… - 这样,您可以看到详细且易于理解的解释,说明您为什么会收到 403。 嗨,感谢您的回答!是的,控制台在您指示的页面中给了我 200 OK 响应,并且我在developers.google.com/apis-explorer/#p/admin/directory_v1/…中的成员测试中也收到了 200 响应(我想通过编程方式获得的数据)@ Roberto,当您 OAuth 批准 Google 控制台时,请检查它请求权限的范围。它们很可能在 URI 中可见。在您的数组中请求相同的范围。 是的,我认为范围没问题,在上面发布的代码中,我将所有内容都放在了 $authArray 数组中。其他建议? 您确定您的 Google 帐户被标记为您的域/组的管理员吗? 【参考方案1】:

问题的根源在于服务账户不是域上的管理员,因此无法访问 Admin SDK Directory API。相反,您需要为您的服务帐户启用domain-wide delegation,然后让服务帐户在发出请求时模拟域管理员:

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

【讨论】:

它有效!是的,完全按照这种方式,发布的代码完美运行,我可以读取所有数据!非常感谢! 救命稻草!谢谢!在 C# 中,您可以通过制作 GoogleCredential 对象的副本来做到这一点: googleCredential = googleCredential.CreateWithUser("user@domain.com"); 我终于可以结束我两天的授权失败了。非常感谢。 @Elliptica 您可以查看this answer 以获取 Python 解决方案 100+ 喜欢这个!很好的答案。

以上是关于Google_Service_Directory - (403) 无权访问此资源/api的主要内容,如果未能解决你的问题,请参考以下文章