使用服务帐户访问用户帐户

Accessing users account with service account

我们需要使用 API 来验证某个用户是否作为托管帐户存在(这意味着,该用户属于我们的 Google 域组织)。

GSuite adminSDK 执行该操作,但是,它需要 OAuth2 身份验证,由经过身份验证的用户授权 - https://developers.google.com/admin-sdk/reports/v1/guides/authorizing

我的问题是,是否有任何方法可以将 API 与服务帐户一起使用,或者是否可以使用任何其他方法来通过服务帐户检索此信息,因为它会在 Server-2-Server 场景中使用.

谢谢, 瓦斯科

如您所知,服务帐户不属于单个最终用户,而是属于应用程序。不过,G Suite 域的管理员可以授权服务帐户访问用户数据,即模拟域中的用户。这称为全域授权

为此,请转到管理控制台并按照步骤 specified here

参考:

由于这完全不明显 - 文档对此进行了“提示”,但没有详细说明,我很难找到任何有效的具体示例。他们都一直返回这个错误:

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]
]

服务帐户必须模拟另一个用户的基本问题。它在底部 link 中提到,以蓝色突出显示:

https://developers.google.com/admin-sdk/directory/v1/guides/delegation

Only users with access to the Admin APIs can access the Admin SDK Directory API, therefore your service account needs to impersonate one of those users to access the Admin SDK Directory API. Additionally, the user must have logged in at least once and accepted the Google Workspace Terms of Service.

但它只是没有点击我应该如何做到这一点 - 这是隐藏在其中一个管理控制台中的某种设置吗?否 - 您将其作为初始连接的一部分传递。

因此,为了将说明放在一个地方并希望避免其他人同样头疼,这些是步骤:

然后我创建了一个 .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;
        }
    }

希望这可以让其他人省去一些麻烦。

服务帐户是应用程序而非个人使用的一种特殊帐户。

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

先决条件:

  • 一个Google云平台项目

    使用 Admin SDK API 启用了具有 domain-wide 委派的服务帐户。
  • A Google 工作区域。

    在该域中使用具有管理员权限的帐户。
  • Visual Studio 2013 年或以后

第 1 步:设置 Google 云平台项目

  • 创建Google 云项目

    Google 云项目需要使用 Google 工作区 API 和构建 Google 工作区 add-ons 或应用程序。 如果您还没有 Google Cloud 项目,请参阅:How to create a Google Cloud project

  • 启用Google工作区APIs

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

    启用Google 工作区API 参考:How to Enable Google Workspace APIs

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

  • 使用 domain-wide 授权创建服务帐户

    创建服务账号参考:How to create service account?

    Domain wide delegation 窗格中,select Manage Domain Wide Delegation

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

    为您的服务帐户下载 p12 文件 contains the private key

第 2 步:设置 Google 工作区

  • 使用

    在Google工作区域中启用API访问

    要在 Google Workspace 域中启用 API 访问权限,请参阅:how to enable API access

  • 将 domain-wide 权限委派给服务帐户

    要代表 Google Workspace 组织中的用户调用 APIs,您的服务帐户需要在 Google Workspace 中被授予 domain-wide 授权管理控制台 由超级管理员帐户

    要在Google 工作区域中委派domain-wide 权限,请参阅:How to Delegating domain-wide authority 到服务帐户

第 3 步:准备 Visual Stodio 项目 -

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

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

    • Install-Package Google.Apis.Auth

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

第 4 步:添加代码

完整示例位于 GitHub

列出来自 Google Workspace Domain

的前 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}");
        }
      }
    }
  }