AdminSettings API 在 C# 控制台应用程序中使用服务帐户

AdminSettings API using service account in a C# Console application

我正在尝试将 Google Admin Settings API 与服务帐户一起使用,但在 C# 控制台应用程序中没有成功。

据我了解,我首先必须获得一个 OAuth 令牌。我为此成功尝试了 2 种方法:使用 Google.Apis.Auth.OAuth2.ServiceAccountCredentials 或手动创建 JWT 断言。

但是当我使用 OAuth 令牌(例如 maximumNumberOfUsers)调用管理设置 API 时,我总是收到 403 错误消息“您无权在域 xxx 上执行操作”消息。

我下载了GAM as the author calls this API too so that I can compose the same HTTP requests. Like explained in GAM wiki, I followed all the steps to create a new Service Account and a new OAuth Client ID so that I can be sure it's not a scope issue. I also activated the debug mode like proposed by Jay Lee 。就像线程评论中解释的那样,它仍然不适用于我的 OAuth 令牌,但对 API 的调用成功使用 GAM OAuth 令牌。

看来这与 OAuth 令牌本身有关。我在创建 OAuth 令牌时遇到的一个问题是我无法指定 "sub" 属性(或 ServiceAccountCredentials 的用户)。如果我添加它,在生成令牌时,即在调用 API 之前,我会收到一个 403 Forbidden 响应,其中 "Requested client not authorized." 作为 error_description。所以也许这是问题所在,但我不知道如何解决它,因为我使用的是管理员电子邮件。

另一种可能性是此 API 需要 OAuth 客户端凭据,因为 GAM 需要 2 种不同类型的凭据,即服务帐户和 OAuth 客户端。由于我只能在我的项目中使用服务帐户凭据,我担心如果是这样的话我会被卡住...

我没有看到其他选项,而且我都坚持使用这两个选项,因此非常感谢您的帮助。谢谢!

我的代码:

public static string GetEnterpriseUsersCount()
{
    string domain = MYDOMAIN;

    string certPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
    certPath = certPath.Substring(0, certPath.LastIndexOf("\") + 1) + "GAMCreds.p12";

    var certData = File.ReadAllBytes(certPath);
    X509Certificate2 privateCertificate = new X509Certificate2(certData, "notasecret", X509KeyStorageFlags.Exportable);

    ServiceAccountCredential credential = new ServiceAccountCredential(
        new ServiceAccountCredential.Initializer(SERVICE_ACCOUNT_EMAIL)
        {
            Scopes = new[] { "https://apps-apis.google.com/a/feeds/domain/" },
            User = ADMIN_EMAIL
        }.FromCertificate(privateCertificate));

    Task<bool> oAuthRequest = credential.RequestAccessTokenAsync(new CancellationToken());
    oAuthRequest.Wait();


    string uri = string.Format("https://apps-apis.google.com/a/feeds/domain/2.0/{0}/general/maximumNumberOfUsers", domain);

    HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
    if (request != null)
    {
        request.Method = "GET";
        request.Headers.Add("Authorization", string.Format("Bearer {0}", credential.Token.AccessToken));

        // Return the response
        using (WebResponse response = request.GetResponse())
        {
            using (StreamReader sr = new StreamReader(response.GetResponseStream()))
            {
                return sr.ReadToEnd();
            }
        }
    }

    return null;
}

编辑: 我专注于下面 Jay Lee 建议的范围,看来缺少的范围是“https://www.googleapis.com/auth/admin.directory.domain'. However, nowhere is this written in Admin Settings API documentation page. At least, I didn't find it. 'https://apps-apis.google.com/a/feeds/domain/”也是必要的,但我已经添加了它到允许的范围列表。谢谢杰!

编辑 2:我也更新了源代码,以便将来能有所帮助。

您需要授予服务帐户的客户端 ID 访问管理员设置范围的权限 API。在正确的正确范围内遵循 Drive domain wide delegation instructions except sub。然后就可以设置sub=没有报错了。