具有服务帐户的工作区域范围委派不适用于一个项目,适用于其他项目
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.Drive
和 SlidesService.Scope.Presentations
因为同一个客户端用于其他需要它们的应用程序。
我们在 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.Drive
和 SlidesService.Scope.Presentations
因为同一个客户端用于其他需要它们的应用程序。