You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.Net邮件客户端对接Office 365账户OAuth2授权异常求助

问题

我正在为应用集成SMTP服务,无Azure使用经验。客户使用不同邮件提供商,可自行配置账户。目前用MailKit对接微软账户(个人及企业版)时遇到问题:已在Microsoft Entra创建支持多租户及个人微软账户的应用,内部组织账户可正常使用,但外部微软账户调用时返回AADSTS50034错误。

测试代码

using MailKit.Net.Smtp;
using MailKit.Security;
using MimeKit;
using Newtonsoft.Json.Linq;

namespace MailKitTest
{
    public class EmailTest
    {

        private SmtpClient smtpClient;

        static async Task<SaslMechanismOAuth2> GetAccessToken(string api_perm)
        {

            var content = new FormUrlEncodedContent(new List<KeyValuePair<string, string>>
            {

                    new KeyValuePair<string, string>("scope", api_perm),
                    new KeyValuePair<string, string>("grant_type", "password"),
                    new KeyValuePair<string, string>("resource", "https://outlook.office365.com/"),
                    new KeyValuePair<string, string>("client_id", "<client_id>"),
                    new KeyValuePair<string, string>("client_secret", "<client_secret>"),
                    new KeyValuePair<string, string>("username", "<test@live.com>"),
                    new KeyValuePair<string, string>("password", "<user_password")
                    
            });

            var client = new HttpClient();

            var response = await client.PostAsync($"https://login.microsoftonline.com/common/oauth2/token", content).ConfigureAwait(continueOnCapturedContext: false); //nosas contas, versão 1

            var jsonString = await response.Content.ReadAsStringAsync();
            var jobj = JObject.Parse(jsonString);
            var token = jobj["access_token"];


            client.Dispose();

            return new SaslMechanismOAuth2("<test@live.com>", token.ToString());
        }

        void sendMail()
        {
            
            
            smtpClient.Authenticated += Client_Authenticated;

            using (smtpClient)
            {

                smtpClient.Connect("smtp.office365.com", 587, SecureSocketOptions.Auto);

                if (smtpClient.AuthenticationMechanisms.Contains("OAUTHBEARER") || smtpClient.AuthenticationMechanisms.Contains("XOAUTH2"))
                {
                    SaslMechanismOAuth2 at = GetAccessToken("SMTP.Send").Result;
                    smtpClient.Authenticate(at);

                }
            }
        }


        private void Client_Authenticated(object? sender, MailKit.AuthenticatedEventArgs e)
        {

            MimeMessage msg = new MimeMessage();
            msg.From.Add(MailboxAddress.Parse("<test@live.com>"));
            msg.To.Add(InternetAddress.Parse("<another_email@test.com>"));
            msg.Subject = "OAUTH Test";
            msg.Body = new TextPart("plain") { Text = "OAUTH Test " + DateTime.Now.ToLongTimeString() };

            smtpClient.Send(msg);
            smtpClient.Disconnect(true);


        }
    }

}

应用配置

  • 认证类型:移动和桌面应用
  • 支持范围:多租户及个人微软账户
  • 已配置权限并创建客户端密钥

错误信息

{
    "correlation_id": "6a4b9d97-b92d-4552-84d2-e1d4c80b61b8",
    "error": "invalid_grant",
    "error_codes": [
        50034
    ],
    "error_description": "AADSTS50034: The user account {EUII Hidden} does not exist in the hotmail.com directory. To sign into this application, the account must be added to the directory. Trace ID: ba97f9bb-5b07-40b2-8a83-aefdcd8d1900 Correlation ID: 6a4b9d97-b92d-4552-84d2-e1d4c80b61b8 Timestamp: 2024-07-18 11:52:17Z",
    "error_uri": "https://login.microsoftonline.com/error?code=50034",
    "timestamp": "2024-07-18 11:52:17Z",
    "trace_id": "ba97f9bb-5b07-40b2-8a83-aefdcd8d1900"
}

咨询:如何让该SMTP客户端(Entra应用)支持所有微软账户使用?


解决方案

1. 替换授权流:密码流不支持个人微软账户

你当前用的password授权类型(资源所有者密码凭证流)只适用于Azure AD组织账户,个人微软账户(live.com/hotmail.com等)完全不支持这个流,这就是AADSTS50034错误的核心原因。

必须改用授权码流(Authorization Code Flow),这是微软官方推荐的桌面/移动应用OAuth2授权方式,能覆盖所有类型的微软账户。

2. 调整应用权限配置

  • 确保在Entra应用中添加的是Delegated权限,SMTP.Send只支持Delegated类型,不要选Application权限。
  • 权限范围指定为https://outlook.office365.com/SMTP.Send,企业账户需要管理员同意,个人账户由用户自己授权即可。

3. 代码修改要点

  • 删除原有的密码流获取token逻辑,改成引导用户跳转到微软授权页面获取授权码,再用授权码兑换access token。
  • 桌面应用可以用本地端口监听回调(比如http://localhost:8080)来接收授权码。
  • 获取到token后,SMTP的OAuth2认证逻辑和原代码一致,直接用SaslMechanismOAuth2对象传入token即可。

4. 其他关键设置

  • 确认Entra应用的"支持的账户类型"设置为**"任何组织目录中的账户和个人微软账户(例如Skype、Xbox)"**,这个配置不能错。
  • 个人微软账户无需开启"不太安全的应用访问",OAuth2方式本身就是安全授权。

内容的提问来源于stack exchange,提问作者MSantos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 20:42:17