使用服务账户访问用户账户

4
我们需要使用API来验证某个用户是否作为托管帐户存在(这意味着属于我们的Google域组织)。
GSuite adminSDK执行该操作,但是它需要OAuth2身份验证,由经过身份验证的用户授权 - https://developers.google.com/admin-sdk/reports/v1/guides/authorizing
我的问题是,是否有任何方法可以使用服务帐户来使用该API,或者使用服务帐户检索此信息的任何其他方法,因为它将用于Server-2-Server场景。
谢谢, Vasco

1
请查看G Suite域宽委托。https://developers.google.com/admin-sdk/reports/v1/guides/delegation - John Hanley
3个回答

3

由于这一点完全不明显——文档中“暗示”了这一点,但没有明确说明,我很难找到任何有效的特定示例。它们一直返回此错误:

Google.GoogleApiException: 'Google.Apis.Requests.RequestError
Not Authorized to access this resource/api [403]
Errors [
    Message[Not Authorized to access this resource/api] Location[ - ] Reason[forbidden] Domain[global]
]

这个问题的基本要点是服务帐户必须模拟另一个用户。在此链接底部以蓝色突出显示:https://developers.google.com/admin-sdk/directory/v1/guides/delegation

只有具有对管理员 API 访问权限的用户才能访问管理员 SDK 目录 API,因此您的服务帐户需要模拟其中一个用户来访问管理员 SDK 目录 API。此外,用户必须至少登录一次并接受 Google Workspace 服务条款。

但是我不知道该如何做到这一点——这是某个管理员控制台中隐藏的设置吗?不是的——您需要将其作为初始连接的一部分传递。
因此,为了将说明放在一个地方,并希望能够节省其他人的相同头痛,以下是步骤: 然后,我创建了一个 .NET Core 控制台应用程序,并安装了以下 NuGet 包:
  • Google.Apis
  • Google.Apis.Auth
  • Google.Apis.Admin.Directory.directory_v1
以下是一个丑陋的概念证明,其中所有内容都能够正常工作:
using System;
using System.IO;
using System.Net;

using Google.Apis.Admin.Directory.directory_v1;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;

namespace GoogleDirectoryTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var dirService = GetDirectoryService(@"C:\tmp\google-cred-sample-12345abdef.json", "user-with-admin-permission-here@mydomainhere.com", "My App Name");
            var list = dirService.Users.List();
            list.Domain = "mydomainhere.com";
            var users = list.Execute();

            foreach (var user in users.UsersValue)
            {
                Console.WriteLine($"{user.Name.FullName}");
            }

            Console.ReadKey();
    }

    static DirectoryService GetDirectoryService(string keyfilepath, string impersonateAccount, string appName)
    {            
        using (var stream = new FileStream(keyfilepath, FileMode.Open, FileAccess.Read))
        {
            var credentials = GoogleCredential.FromStream(stream).CreateWithUser(impersonateAccount);
            if (credentials.IsCreateScopedRequired)
                credentials = credentials.CreateScoped(new[] { DirectoryService.Scope.AdminDirectoryUserReadonly });

            var service = new DirectoryService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credentials,
                ApplicationName = appName,
            });
            return service;
        }
    }

希望这篇文章能够避免其他人的一些麻烦。


2

谢谢。这正是我需要的!然而,来自Google的解决方案看起来很奇怪,因为服务帐户无法直接访问,但可以模拟(无需最终用户进行任何用户交互)。 - Vasco Silva

0

服务帐号是应用程序使用的一种特殊类型的帐号,而不是人员使用的帐号。

您可以使用服务帐号来访问机器人帐号本身的数据或执行操作,或代表 Google Workspace 或 Cloud Identity 用户访问数据。

先决条件:

  • 一个 Google Cloud 平台项目

    启用了管理员 SDK API 的服务帐号,并进行域范围委派。
  • 一个 Google Workspace 域。

    该域中具有管理员权限的帐户。
  • Visual Studio 2013 或更高版本

步骤 1:设置 Google Cloud 平台项目

  • 创建 Google Cloud 项目

    使用 Google Workspace API 和构建 Google Workspace 插件或应用程序需要一个 Google Cloud 项目。如果您没有 Google Cloud 项目,请参阅:如何创建 Google Cloud 项目

  • 启用 Google Workspace API

    在使用 Google API 之前,需要在 Google Cloud 项目中启用它们。

    有关启用 Google Workspace API 的方法,请参阅:如何启用 Google Workspace API

    对于此示例,您正在启用 Admin SDK Directory API,数据范围为 /auth/admin.directory.user.readonly

  • 创建具有域委派的服务帐号

    要创建服务帐号,请参阅:如何创建服务帐号?

    在“域委托”窗格中,选择“管理域委托”。

  • 下载服务帐号私钥(p12 格式)

    下载包含您的服务帐号私钥的 p12 文件 文件

步骤二:设置Google Workspace

  • 启用Google Workspace域中的API访问

    要在Google Workspace域中启用API访问,请参考:如何启用API访问

  • 将域范围授权委派给服务帐户

    为了代表Google Workspace组织中的用户调用API,您的服务帐户需要在Google Workspace管理控制台中获得超级管理员帐户的域范围授权委派。

    要在Google Workspace域中进行域范围授权委派,请参考:如何将域范围授权委派到服务帐户

步骤三:准备Visual Studio项目 -

  • 在Visual Studio中创建一个新的Visual C#控制台应用程序(.NET Framework)项目。

  • 打开NuGet包管理器控制台,选择包源nuget.org,并运行以下命令:

    • Install-Package Google.Apis.Auth

    • Install-Package Google.Apis.Admin.Directory.directory_v1

步骤4:添加代码

完整示例请参见GitHub

列出来自Google Workspace域的前10个用户别名

  /// <summary>
  /// Example how to list all users from google workspace domain, using a service account (user impersonation).
  /// </summary>
  internal class Program {
    static void Main(string[] args) {
      // Scope for only retrieving users or user aliases.
      string[] _scopes = {
        "https://www.googleapis.com/auth/admin.directory.user.readonly"
      };

      var _paramters = new SACInitializeParameters(
        // The service account ID (typically an e-mail address like: *@*iam.gserviceaccount.com)
        serviceAccountId: "[Service Account ID]",
        // The full path; name of a certificate file
        x509CertificateFilePath: "[X509 Certificate File]",
        // The email address of the user you trying to impersonate
        impersonateEmail: "[User Email]",
        // The scopes which indicate API access your application is requesting
        scopes: _scopes);


      using (var directoryService = DirectoryServiceFactory.CreateDirectoryService(_paramters)) {
        // Retrieves a paginated list of either deleted users or all users in a domain.
        var request = directoryService.Users.List();
        // The unique ID for the customer's Google Workspace account
        // the `my_customer` alias represent current identety account's
        request.Customer = "my_customer";
        request.MaxResults = 10;
        var response = request.Execute();

        foreach (var user in response.UsersValue) {
          System.Console.WriteLine($"{user.Name.FullName}, {user.PrimaryEmail}, {user.Id}");
        }
      }
    }
  }

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