如何正确设置 Windows 桌面应用程序以通过 Office 365 发送电子邮件?

How to properly set up a Windows Desktop application to send emails via Office 365?

提问人:Mark 提问时间:11/17/2023 更新时间:11/17/2023 访问量:18

问:

我们有一个桌面应用程序,可以代表用户发送电子邮件(用于发票、收据等)。以前,我们一直使用基本的 SMTP 身份验证,但现在我们正在为需要 OAuth 2.0 的服务(如 Exchange 365 online)添加对 OAuth 2.0 的支持。因此,应用程序需要针对用户正在运行的任何任意 Exchange 365 服务器进行身份验证,并向任意数量的收件人(其客户)发送带有附件的电子邮件。这对我们来说都是新的,所以我想确保我们设置正确。

以下是我到目前为止所做的:

  1. 应用程序已在我们的公司 Azure AD 站点上注册。我已经为它分配了 Mail.Send 权限(以及其他权限)。Azure AD permissions

  2. 我们使用 Microsoft 标识客户端库进行身份验证。所有函数调用似乎都正常工作,我收到登录提示,登录,并在手机的 Authenticator 应用程序上验证登录。这些函数返回一个令牌。鉴于我们想要针对 Office 365 上的任何组织/域进行身份验证,我认为我们需要使用“通用”TenantID,这是正确的吗?

    Dim Options As New PublicClientApplicationOptions
    Options.ClientId = pClientID
    Options.TenantId = pTenantID
    Options.RedirectUri = "https://login.microsoftonline.com/common/oauth2/nativeclient"
    
    Dim publicClientApplication As IPublicClientApplication = PublicClientApplicationBuilder.CreateWithApplicationOptions(Options).Build
    
    Dim scopes() As String = {
        "email",
        "offline_access",
        "https://outlook.office.com/Mail.Send"
    }
    
    Try
    
        Dim CM_EmailServerSetting As ICM_EmailServerSetting = CCM_EmailServerSettingServices.GetEmailServerSettingForApplication()
    
        Dim authToken As AuthenticationResult = Await publicClientApplication.AcquireTokenInteractive(scopes).WithParentActivityOrWindow(Me).WithLoginHint(CM_EmailServerSetting.EmailAddress).ExecuteAsync()
    
  3. 然后,我们使用 SMTP 协议连接到指定的服务器,但使用 OAuth2 对象。

    将 oauth2 调暗为 MailKit.Security.SaslMechanism 将 EmailClient 调暗为新 Net.Smtp.SmtpClient() EmailClient.Connect(CM_EmailServerSetting.SMTPServerAddress, CM_EmailServerSetting.Port)

        If (EmailClient.AuthenticationMechanisms.Contains("OAUTHBEARER")) Then
            oauth2 = New MailKit.Security.SaslMechanismOAuthBearer(authToken.Account.Username, authToken.AccessToken)
        Else
            oauth2 = New MailKit.Security.SaslMechanismOAuth2(authToken.Account.Username, authToken.AccessToken)
        End If
    
        Await EmailClient.AuthenticateAsync(oauth2)
    

上述对 AuthenticateAsync 的调用会引发一个异常,即为租户禁用了 SMTP AUTH。我们似乎正在尝试使用 OAuth2 协议进行连接,那么我错过了什么?是否需要在 Azure 上授予其他权限?(这对我们来说都是新的)

电子邮件 azure-active-directory office365 桌面应用程序 mailkit

评论


答:

0赞 Mark 11/17/2023 #1

代码很好。已为测试帐户禁用 SMTP。

对不起大家。保留问答,以防万一其他人落入同样的陷阱。