具有服务帐户的工作区域范围委派不适用于一个项目,适用于其他项目

Workspace Domain-wide Delegation with service account not working for one project, works for others

我们在 GCP 上有不同的项目,我们用它们来访问不同的 Google API。其中大部分仅供内部使用。

在这种特殊情况下,我们有 2 个项目,都使用服务帐户,并且都允许在相同范围内的 Workspace Domain-wide Delegation。他们几乎是彼此的克隆。

我使用相同的代码 (Spreadsheet.Get()) 执行一个简单的请求,并使用项目 1 凭据运行。我使用项目 2 凭据执行相同的请求,但它不起作用。

自 Workspace Domain-wide Delegation 以来,它激活了共享到我的电子邮件的电子表格,我也使用我的电子邮件连接到 API(与项目 1 一起使用,所以这不是问题)(模拟用户)

唯一的区别是一个项目在外部有 OAuth 同意屏幕(只有 100 个用户,因为我们只在内部使用它,无论如何..)而另一个是内部的,但这与此无关对吧?

问题可能来自哪里?我是否需要重新创建不起作用的项目?

这是错误信息:

Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested

编辑以回答评论,但此代码的工作取决于我们使用的服务帐户

正在生成凭据:

internal static ServiceCredential GetApiCredentialsFromJson(string jsonCredentialsPath, string mailToMimic)
        {
            string jsonCertificate = File.ReadAllText(jsonCredentialsPath);
            string privateKey = Regex.Match(jsonCertificate, @"(?<=""private_key"": "")(.*)(?="")").Value.Replace(@"\n", "");
            string accountEmail = Regex.Match(jsonCertificate, @"(?<=""client_email"": "")(.*)(?="")").Value;

            ServiceAccountCredential.Initializer credentials = new ServiceAccountCredential.Initializer(accountEmail)
            {
                Scopes = _scopes,
                User = mailToMimic
            }.FromPrivateKey(privateKey);

            return new ServiceAccountCredential(credentials);
        }

使用凭据:

internal GoogleSheetService(ServiceCredential credentials)
    {
        SheetsService = new SheetsService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credentials
        });
        SheetsService.HttpClient.Timeout = TimeSpan.FromSeconds(100);
    }

Workspace 控制台上的云端硬盘、广告和电子表格范围允许使用客户端 ID。

答案很简单,但我们得自己想办法。

您在初始化客户端时添加到应用中的范围需要与您在 Google 管理广泛委派页面中添加的范围完全相同。 即使您的应用程序或应用程序的一部分不需要全部。

C# 示例:

        private static readonly string[] _scopes = { DriveService.Scope.Drive, SheetsService.Scope.Spreadsheets, SlidesService.Scope.Presentations };

        ServiceAccountCredential.Initializer credentials = new ServiceAccountCredential.Initializer(accountEmail)
        {
            Scopes = _scopes,
            User = mailToMimic
        }.FromPrivateKey(privateKey);

        return new ServiceAccountCredential(credentials);

这里我的应用程序只需要 SheetsService.Scope.Spreadsheets 但我必须添加 DriveService.Scope.DriveSlidesService.Scope.Presentations 因为同一个客户端用于其他需要它们的应用程序。