GmailAPI 服务帐户访问是否*需要*委派全域权限以仅从所有者的地址发送邮件?
Does GmailAPI service account access *require* Delegating domain-wide authority to send mail only from owner's address?
我正在尝试使用 GmailAPI(使用 OAUTH)从 Windows 应用程序向公司内部人员发送电子邮件。电子邮件只需要来自一个地址——一个专门为此目的创建的地址。我设置了一个服务帐户并完成了生成凭据的过程。管理员批准了 'Send' 和 'Compose'.
的授权范围
但是当我尝试发送消息时,我收到了这个错误:
Google.Apis.Auth.OAuth2.Responses.TokenResponseException: 'Error:"invalid_request", Description:"Invalid impersonation "sub" field.", Uri:""'
我试过使用服务帐户电子邮件地址而不是上面的 "me"。当我这样做时,出现此错误:
Google.Apis.Auth.OAuth2.Responses.TokenResponseException: 'Error:"unauthorized_client", Description:"Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested.", Uri:""'
我还没有将域范围的权限委托给服务帐户。这对我们来说似乎很危险。不清楚这样做是否让这个帐户能够访问每个人的电子邮件?在我看来,如果 Google 云项目是从将发送电子邮件的帐户创建的,并且如果服务帐户也与该项目和同一用户电子邮件相关联,那么它应该已经有权从那个帐户发送电子邮件。为什么需要全域访问?
需要吗?还是我有其他问题?我找到的很多访问 Gmail API 的例子都已经过时了,我不确定我是否只是遗漏了一些其他的拼图。如果我只是希望服务帐户能够从那个地址(创建服务帐户的同一地址)发送电子邮件,是否有必要对服务帐户进行全域授权?
这是我使用的代码:
string[] Scopes = {GmailService.Scope.GmailSend };
string ApplicationName = "XXXXXX";
ServiceAccountCredential credential;
string serviceAccountEmail = "xxxxxx@xxxxx.iam.gserviceaccount.com";
string jsonfile = "xxxxxx-f2fea9069fb5.json";
using (Stream stream = new FileStream(@jsonfile, FileMode.Open, FileAccess.Read, FileShare.Read))
{
credential = (ServiceAccountCredential)
GoogleCredential.FromStream(stream).UnderlyingCredential;
var initializer = new ServiceAccountCredential.Initializer(credential.Id)
{
User = "me",
Key = credential.Key,
Scopes = Scopes
};
credential = new ServiceAccountCredential(initializer);
}
// Create Gmail API service.
var service = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
string plainText = "To: someone@somewhere.com\r\n" +
"Subject: subject Test\r\n" +
"Content-Type: text/html; charset=us-ascii\r\n\r\n" +
"<h1>Body Test </h1>";
var newMsg = new Google.Apis.Gmail.v1.Data.Message();
newMsg.Raw = Base64UrlEncode(plainText.ToString());
service.Users.Messages.Send(newMsg, "me").Execute();
感谢任何回复。
如果您使用的是 Gsuite 域并且已设置 domain wide deligation
,则服务帐户仅适用于 Gmail
另请记住,使用 gmail api 可能会花费您验证应用程序的费用。我不确定是否供内部使用,这可能重要也可能无关紧要。
我正在尝试使用 GmailAPI(使用 OAUTH)从 Windows 应用程序向公司内部人员发送电子邮件。电子邮件只需要来自一个地址——一个专门为此目的创建的地址。我设置了一个服务帐户并完成了生成凭据的过程。管理员批准了 'Send' 和 'Compose'.
的授权范围但是当我尝试发送消息时,我收到了这个错误:
Google.Apis.Auth.OAuth2.Responses.TokenResponseException: 'Error:"invalid_request", Description:"Invalid impersonation "sub" field.", Uri:""'
我试过使用服务帐户电子邮件地址而不是上面的 "me"。当我这样做时,出现此错误:
Google.Apis.Auth.OAuth2.Responses.TokenResponseException: 'Error:"unauthorized_client", Description:"Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested.", Uri:""'
我还没有将域范围的权限委托给服务帐户。这对我们来说似乎很危险。不清楚这样做是否让这个帐户能够访问每个人的电子邮件?在我看来,如果 Google 云项目是从将发送电子邮件的帐户创建的,并且如果服务帐户也与该项目和同一用户电子邮件相关联,那么它应该已经有权从那个帐户发送电子邮件。为什么需要全域访问?
需要吗?还是我有其他问题?我找到的很多访问 Gmail API 的例子都已经过时了,我不确定我是否只是遗漏了一些其他的拼图。如果我只是希望服务帐户能够从那个地址(创建服务帐户的同一地址)发送电子邮件,是否有必要对服务帐户进行全域授权?
这是我使用的代码:
string[] Scopes = {GmailService.Scope.GmailSend };
string ApplicationName = "XXXXXX";
ServiceAccountCredential credential;
string serviceAccountEmail = "xxxxxx@xxxxx.iam.gserviceaccount.com";
string jsonfile = "xxxxxx-f2fea9069fb5.json";
using (Stream stream = new FileStream(@jsonfile, FileMode.Open, FileAccess.Read, FileShare.Read))
{
credential = (ServiceAccountCredential)
GoogleCredential.FromStream(stream).UnderlyingCredential;
var initializer = new ServiceAccountCredential.Initializer(credential.Id)
{
User = "me",
Key = credential.Key,
Scopes = Scopes
};
credential = new ServiceAccountCredential(initializer);
}
// Create Gmail API service.
var service = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
string plainText = "To: someone@somewhere.com\r\n" +
"Subject: subject Test\r\n" +
"Content-Type: text/html; charset=us-ascii\r\n\r\n" +
"<h1>Body Test </h1>";
var newMsg = new Google.Apis.Gmail.v1.Data.Message();
newMsg.Raw = Base64UrlEncode(plainText.ToString());
service.Users.Messages.Send(newMsg, "me").Execute();
感谢任何回复。
如果您使用的是 Gsuite 域并且已设置 domain wide deligation
,则服务帐户仅适用于 Gmail另请记住,使用 gmail api 可能会花费您验证应用程序的费用。我不确定是否供内部使用,这可能重要也可能无关紧要。