使用Google App Engine应用程序更新Google Group订阅

3
我正在谷歌应用引擎(PHP)上构建一个小应用程序,旨在将外部信息源与谷歌群组同步,以便拥有最新的邮件列表。(它应当作为GAE定期任务运行)。
谷歌应用引擎项目和谷歌群组都在GSuite域内。 源代码在这里,请参见firestore2ggroup.php。
我的问题与安全有关,当我尝试调用API时,我会收到403错误,而没有其他细节。
{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "forbidden",
    "message": "Not Authorized to access this resource/api"
   }
  ],
  "code": 403,
  "message": "Not Authorized to access this resource/api"
 }
}

我按照这里描述的步骤作为起点,因为它与我的需求相近:

https://medium.com/@Skaaptjop/access-gsuite-apis-on-your-domain-using-a-service-account-e2a8dbda287c

因此,我按照以下步骤进行了操作:

  • 在Google Cloud Console中:

    • 部署Google App Engine项目
    • 转到IAM,服务帐户,复制GAE服务帐户的唯一密钥并启用“域宽委派”
    • 创建JSON私钥
    • 使用“服务目录管理员”(以及Cloud Data Store用户用于Firestore)更新服务帐户
  • 在GSuite管理者中:

    • 以域的管理员身份连接到admin.google.com
    • 转到Security,然后是“高级设置”,再是“管理API客户端访问”
    • 添加一个
    • 将服务帐户唯一标识粘贴为客户端名称
    • https://www.googleapis.com/auth/admin.directory.group.member(查看和管理您域上的组订阅)

更新:我甚至尝试添加更多权限,但仍然无法正常工作:

enter image description here

在我的项目中,我复制了JSON私钥,并在app.yaml中设置了变量GOOGLE_APPLICATION_CREDENTIALS和文件名。我使用了Google库来访问Google组:composer require google/apiclient:^2.0。
try
{
  $client = new Google_Client();
  $client->setApplicationName('Pegass2GGroup');
  $client->setScopes(
    [
      Google_Service_Directory::ADMIN_DIRECTORY_GROUP,
      Google_Service_Directory::ADMIN_DIRECTORY_GROUP_MEMBER,
      Google_Service_Directory::ADMIN_DIRECTORY_USER
    ]);
  $client->useApplicationDefaultCredentials(true);
  $access_token = $client->fetchAccessTokenWithAssertion();

  print_r($access_token);

  $service = new Google_Service_Directory($client);

  /** @var $members  Google_Service_Directory_Members */
  $members = $service->members->listMembers($MAILING_LIST);

  /** @var $member  Google_Service_Directory_Member */
  foreach ($members as $member)
  {
    print_r($member->getEmail());
  }
  echo "</pre>";
}
catch(Exception $e)
{
  print_r($e);
  echo "</pre>";
}

我可以告诉私钥已经加载,因为print_r($e)返回了一个长的异常并且密钥被列出。 print_r($access_token); 返回以下内容:
Array
(
    [access_token] => dag2qssffdVpRZEr...0BsM_QUgQ
    [expires_in] => 3599
    [token_type] => Bearer
    [created] => 1586787451
)

$MAILING_LIST:是邮件列表的完整电子邮件地址

1个回答

0

所以上面的代码缺少模拟。

$client->setSubject($EMAIL_TO_IMPERSONATE); //admin@mydomain.com

在触及域中其他成员的数据时,要扮演此电子邮件的角色。

然后我得到了这个错误:

(
    [errors:protected] => 
    [message:protected] => {
  "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."
}

这是因为我正在请求:

  Google_Service_Directory::ADMIN_DIRECTORY_GROUP,
  Google_Service_Directory::ADMIN_DIRECTORY_GROUP_MEMBER,
  Google_Service_Directory::ADMIN_DIRECTORY_USER

但是我忘记在 GSuite API 安全管理中添加以下内容:

  Google_Service_Directory::ADMIN_DIRECTORY_USER

添加后,它就可以工作了。 因此,如果您请求一组角色,则必须授予所有角色。 即使我没有使用Google_Service_Directory :: ADMIN_DIRECTORY_USER,但事实上我在连接时询问它并且其中一个未被授予,整个连接也会被阻止。

我认为我只需要 Google_Service_Directory :: ADMIN_DIRECTORY_GROUP_MEMBER

到目前为止,我仅需列出组的成员:

184920....0484899(客户端ID)

https://www.googleapis.com/auth/admin.directory.group,https://www.googleapis.com/auth/admin.directory.group.member,https://www.googleapis.com/auth/apps.groups.settings,https://www.googleapis.com/auth/groups,https://www.googleapis.com/auth/admin.directory.user


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接