2025年10月17日 星期五

[研究]System.Net.Mail.MailMessage 寄信成功,MailKit 出現 "5.7.60 SMTP; Client does not have permissions to send as this sender"

[研究]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):

  1. 選該信箱(例如 shared@example.com)
  2. 點「Mailbox Delegation」
  3. 在 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 錯誤

********************************************************************************

敝人最後用 "確保寄件人與登入帳號一致" 的方法,解決問題了。

(完)

相關

沒有留言:

張貼留言