如何仅在 ASP.NET Core 控制台应用程序中使用服务帐户详细信息发送电子邮件?

Posted

技术标签:

【中文标题】如何仅在 ASP.NET Core 控制台应用程序中使用服务帐户详细信息发送电子邮件?【英文标题】:How to send email using service account details only in ASP.NET Core console application? 【发布时间】:2021-11-07 10:31:56 【问题描述】:

我有 gmail API 服务帐户详细信息 = 客户端 ID 和服务帐户。如何在没有 OAuth 的情况下从一个 ID 向另一个 ID 发送电子邮件?

我想仅使用服务帐户凭据授权此电子邮件发送过程。

是否有可以帮助满足此要求的 nuget 包?

【问题讨论】:

“从一个身份到另一个身份”是什么意思?请注意(一般而言)您不能代表其他人通过 Internet 发送电子邮件,除非用户通过他们的电子邮件提供商授予您某种委派权限。 (还要注意像 SPF、DKIM 等,除非您做的事情正确,否则所有这些都会导致您的出站电子邮件被标记为垃圾邮件......) "仅使用服务帐户凭据。" - “服务帐户凭据”到底是什么意思?如果您指的是 Windows 服务帐户,那么这完全不相关(除非您使用的是 Microsoft Exchange 之类的本地 MX/MTA)。 请详细说明您提到 OAuth 的原因 - 虽然 GMail 确实支持 OAuth,但仍然需要用户自己授予 your 应用程序代码对用户邮箱的权限(在-turn 表示您的应用程序将由 GMail 发出access_token) - 您不能在 OAuth2 中使用 client_credentials 代表 GMail 中的任何人发送电子邮件:“没有衬衫,没有鞋子,没有 access_token,没有服务”. @Dai 对于通过谷歌工作区帐户正确配置的服务帐户,这不是真的,您可以代表工作区用户发送电子邮件。 delegate_settings 【参考方案1】:

如何在没有 OAuth 的情况下从一个 ID 向另一个 ID 发送电子邮件?

我假设您的意思是如何在不弹出 Oauth2 同意屏幕的情况下发送电子邮件。

一旦您在 Google 工作区帐户中正确配置了权限,就可以使用服务帐户来执行此操作。您授予服务帐户代表您的域用户之一执行操作。这样,服务帐户可以以该用户的身份发送电子邮件,而无需用户同意该访问权限,因为您已通过 google 工作区对其进行了预授权。

以下代码将向您展示如何授权您的应用程序使用服务帐号。

class Program
    
        public static string Base64Encode(string plainText)
        
            var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
            return System.Convert.ToBase64String(plainTextBytes);
        

    public static void SendMail()
    
        try
        
            string ApplicationName = "Gmail API .NET Quickstart";
            const string serviceAccount = "xxxx@xxxx-api.iam.gserviceaccount.com";

            var certificate = new X509Certificate2(@"c:\XXXX.p12", "notasecret", X509KeyStorageFlags.Exportable);

            var gsuiteUser = "YourDomain@YourDomain.com";

            var serviceAccountCredentialInitializer = new ServiceAccountCredential.Initializer(serviceAccount)
            
                User = gsuiteUser,
                Scopes = new[]  GmailService.Scope.GmailSend, GmailService.Scope.GmailLabels 

            .FromCertificate(certificate);

            var credential = new ServiceAccountCredential(serviceAccountCredentialInitializer);
            if (!credential.RequestAccessTokenAsync(CancellationToken.None).Result)
                throw new InvalidOperationException("Access token failed.");

            var service = new GmailService(new BaseClientService.Initializer()
            
                HttpClientInitializer = credential,
                ApplicationName = ApplicationName,
            );

            var mailMessage = new MailMessage();
            mailMessage.From = new MailAddress("se@Yourdomain.com");
            mailMessage.To.Add("ddddd@hotmail.com");
            mailMessage.ReplyToList.Add("se@Yourdomain.com");
            mailMessage.Subject = "test";
            mailMessage.Body = "<h1>sdf</h1>";
            mailMessage.IsBodyhtml = true;

            //foreach (System.Net.Mail.Attachment attachment in email.Attachments)
            //
            //    mailMessage.Attachments.Add(attachment);
            //

            var mimeMessage = MimeKit.MimeMessage.CreateFromMailMessage(mailMessage);

            var gmailMessage = new Message
            
                Raw = Base64Encode(mimeMessage.ToString())
            ;

            Message message1 = new Message();
            UsersResource.MessagesResource.SendRequest sendRequest = service.Users.Messages.Send(gmailMessage, "me");
            var s = sendRequest.Execute();


            Console.WriteLine("Message delivered!");
        
        catch (Exception ep)
        
            Console.WriteLine(ep.ToString());
        
    

诀窍是记住正确设置域范围的委派并确定服务帐户将模拟哪个用户并记住添加该电子邮件

没有谷歌工作区

如果您没有 google 工作区帐户,则无法使用服务帐户。您可能需要考虑使用 smtp 服务器。

【讨论】:

我收到此错误消息:System.AggregateException:发生了一个或多个错误。 (错误:“invalid_grant”,描述:“无效的 JWT 签名。”,Uri:“”)@DalmTo 服务帐户的无效授权听起来很奇怪。你有没有机会重新生成 p12 文件?您确定您在工作区帐户上正确设置了委派? 有什么办法可以在windows上手动制作p12证书?我有服务帐户详细信息。但我无法重新生成 p12 证书。 @DalmTo p12必须在谷歌云控制台上创建,用于授权谷歌授权服务器。检查youtube.com/watch?v=asrCdWFrF0A 请记住,您需要从工作区域中的用户创建它。您不能使用标准的 gmail 帐户来创建它。 感谢您的帮助。 @DaImTo

以上是关于如何仅在 ASP.NET Core 控制台应用程序中使用服务帐户详细信息发送电子邮件?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 ASP.NET Core 解决 REACT 中的 CORS 错误

仅在文件上传中出现 Asp.Net Core API CORS 策略错误

如何对 ASP.NET Core 控制器或模型对象进行单元测试?

如何在 Asp.Net Core 的控制器操作和区域中限制参数类型

asp.net core mvc权限控制:分配权限

如何在 ASP.NET Core 3.1 中使用 Java?