GSuite adminSDK执行该操作,但是它需要OAuth2身份验证,由经过身份验证的用户授权 - https://developers.google.com/admin-sdk/reports/v1/guides/authorizing。
我的问题是,是否有任何方法可以使用服务帐户来使用该API,或者使用服务帐户检索此信息的任何其他方法,因为它将用于Server-2-Server场景。
谢谢, Vasco
由于这一点完全不明显——文档中“暗示”了这一点,但没有明确说明,我很难找到任何有效的特定示例。它们一直返回此错误:
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]
]
但是我不知道该如何做到这一点——这是某个管理员控制台中隐藏的设置吗?不是的——您需要将其作为初始连接的一部分传递。只有具有对管理员 API 访问权限的用户才能访问管理员 SDK 目录 API,因此您的服务帐户需要模拟其中一个用户来访问管理员 SDK 目录 API。此外,用户必须至少登录一次并接受 Google Workspace 服务条款。
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;
}
}
希望这篇文章能够避免其他人的一些麻烦。
您可能知道,服务账户不属于个人终端用户,而是属于应用程序。然而,G Suite域的管理员可以授权服务帐户访问用户数据,即冒充域中的用户。这被称为域范围委派。
要实现此目的,请转到管理控制台并按照此处指定的步骤进行操作。
服务帐号是应用程序使用的一种特殊类型的帐号,而不是人员使用的帐号。
您可以使用服务帐号来访问机器人帐号本身的数据或执行操作,或代表 Google Workspace 或 Cloud Identity 用户访问数据。
使用 Google Workspace API 和构建 Google Workspace 插件或应用程序需要一个 Google Cloud 项目。如果您没有 Google Cloud 项目,请参阅:如何创建 Google Cloud 项目
在使用 Google API 之前,需要在 Google Cloud 项目中启用它们。
有关启用 Google Workspace API 的方法,请参阅:如何启用 Google Workspace API
对于此示例,您正在启用 Admin SDK Directory API,数据范围为 /auth/admin.directory.user.readonly
。
要创建服务帐号,请参阅:如何创建服务帐号?
在“域委托”窗格中,选择“管理域委托”。
下载包含您的服务帐号私钥的 p12 文件 文件。
要在Google Workspace域中启用API访问,请参考:如何启用API访问
为了代表Google Workspace组织中的用户调用API,您的服务帐户需要在Google Workspace管理控制台中获得超级管理员帐户的域范围授权委派。
要在Google Workspace域中进行域范围授权委派,请参考:如何将域范围授权委派到服务帐户
Install-Package Google.Apis.Auth
Install-Package Google.Apis.Admin.Directory.directory_v1
完整示例请参见GitHub
/// <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}");
}
}
}
}