[研究]System.Net.Mail.MailMessage 寄信成功,MailKit 出現 "5.7.60 SMTP; Client does not have permissions to send as this sender"
2025-10-17
環境:Visual Studio 2022 + ASP.NET + WebForm + Web Application + C# + SQL Server 2019 + SQL Server Management Studio (SSMS) 19
********************************************************************************
在 Exchange 上相同的帳號、密碼,
用 System.Net.Mail.MailMessage 透過 Exchange 寄信正常
用 MailKit 透過 Exchange 寄信出現 "5.7.60 SMTP; Client does not have permissions to send as this sender"
怎麼回事 ?
ChatGPT
這個狀況非常常見,原因主要是 Exchange 的身分驗證與寄件人權限機制 導致的。
MailKit 嘗試以一個「未被授權的寄件者」身份發信,Exchange 判定該帳號沒有 “Send As” 權限。
🧠 背後原理差異
1️⃣ System.Net.Mail 與 Exchange 的行為
System.Net.Mail 通常使用傳統 SMTP AUTH(登入帳號作為寄件者),Exchange 會「自動容忍」寄件人欄(From:)與登入帳號相同的情況。有些舊 Exchange 甚至會自動改寫寄件人成為登入者帳號。
例如:
var msg = new MailMessage("userA@example.com", "test@example.com", "Test", "Hello");
var smtp = new SmtpClient("exchange.example.com");
smtp.Credentials = new NetworkCredential("userA@example.com", "password");
smtp.Send(msg);
|
✅ 正常寄出。
2️⃣ MailKit 的行為
MailKit 比較嚴格,它會「照原樣」送出 MAIL FROM: 與 From: 標頭。
如果你的程式這樣寫:
var message = new MimeMessage();
message.From.Add(new MailboxAddress("userB@example.com"));
message.To.Add(new MailboxAddress("test@example.com"));
message.Subject = "Test";
message.Body = new TextPart("plain") { Text = "Hello" };
using (var client = new SmtpClient())
{
client.Connect("exchange.example.com", 587, SecureSocketOptions.StartTls);
client.Authenticate("userA@example.com", "password");
client.Send(message);
client.Disconnect(true);
}
|
Exchange 看到:
-
登入帳號:
userA@example.com -
寄件人:
userB@example.com
它就會拒絕,回:
5.7.60 SMTP; Client does not have permissions to send as this sender
✅ 解法
✅ 方法一:確保寄件人與登入帳號一致
最簡單:
message.From.Add(new MailboxAddress("userA@example.com"));
|
或乾脆讓 From 直接由登入帳號動態填入。
✅ 方法二:給帳號「Send As」或「Send on Behalf」權限
如果真的需要用別的寄件人(例如共用信箱),請在 Exchange 管理介面設定:
在 Exchange Admin Center (EAC):
- 選該信箱(例如 shared@example.com)
- 點「Mailbox Delegation」
- 在 Send As 欄位中加入該使用者帳號(userA@example.com)→ 或者在 Send on behalf 欄位中加入
完成後,MailKit 才能以該信箱名義發信。
✅ 方法三:確認使用的驗證方式
有時 System.Net.Mail 與 MailKit 使用不同協議層:
| 類別 | 驗證方式 | 備註 |
|---|---|---|
| System.Net.Mail | 基於 NTLM / Integrated Auth | 內部網域帳號可通過 |
| MailKit | 預設使用 AUTH LOGIN / PLAIN | 需明確授權 |
若你是內網 Exchange,可嘗試:
client.Authenticate(new SaslMechanismNtlm("DOMAIN\\userA", "password"));
|
或
client.Authenticate(new SaslMechanismGssapi()); |
(取決於伺服器允許的機制)
🧩 小結
| 原因 | 解法 |
|---|---|
寄件人 (From:) 與登入帳號不一致 |
改為相同 |
| 需要代寄別的信箱 | 在 Exchange 給「Send As」或「Send on behalf」權限 |
| 驗證機制不同 | 改用 NTLM / GSSAPI |
| System.Net.Mail 自動容忍,MailKit 不會 | 屬於設計差異,非 MailKit 錯誤 |
********************************************************************************
敝人最後用 "確保寄件人與登入帳號一致" 的方法,解決問題了。
相關
沒有留言:
張貼留言