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 可能会花费您验证应用程序的费用。我不确定是否供内部使用,这可能重要也可能无关紧要。