Mailbox unavailable. The server response was: 5.7.1 Client does not have permissions to send as this sender
Can't send mail using SmtpClient
The server responds with 5.7.1 Client was not authenticated but only if you do not set UseDefaultCredentials
to true
. This indicates that the NetworkCredential
that you are using is in fact wrong.
Either the user name or password is wrong or perhaps you need to specify a domain? You can use another constructor to specify the domain:
new NetworkCredential("MyUserName", "MyPassword", "MyDomain");
Or perhaps the user that you specify does not have the necessary rights to send mail on the SMTP server but then I would expect another server response.
SmtpClient.UseDefaultCredentials Property
Remarks
Some SMTP servers require that the client be authenticated before the server sends email on its behalf. Set this property to true
when this SmtpClient object should, if requested by the server, authenticate using the default credentials of the currently logged on user. For client applications, this is the desired behavior in most scenarios.
Credentials information can also be specified using the application and machine configuration files. For more information, see <mailSettings> Element (Network Settings).
If the UseDefaultCredentials property is set to false,
then the value set in the Credentials property will be used for the credentials when connecting to the server. If the UseDefaultCredentials property is set to false
and the Credentials property has not been set, then mail is sent to the server anonymously.
Caution
If you provide credentials for basic authentication, they are sent to the server in clear text. This can present a security issue because your credentials can be seen, and then used by others.
1. UseDefaultCredentials为true,那么使用using the default credentials of the currently logged on user
2.UseDefaultCredentials为false
2.1 如果配置了credentials,就使用credentials
2.2 如果没有配置credentials,那么就是匿名登陆
Why SmtpClient.UseDefaultCredentials is ignored?
If UseDefaultCredentials is set to true, it does NOT mean use the values in the Credentials property. Instead, it means use the credentials of the "currently logged on user", which in the case of IIS web apps will usually be the app pool identity, and in the case of a Windows service is the identity of the service, and in the case of a desktop application, it's the identity of the user logged into Windows.
See the Microsoft document (https://msdn.microsoft.com/en-us/library/system.net.mail.smtpclient.usedefaultcredentials(v=vs.110).aspx) where it states that if UseDefaultCredentials is false (the default) and you don't provide anything in the Credentials property, "then mail is sent to the server anonymously".
Confused with the SmtpClient.UseDefaultCredentials Property
So why would me explicitly setting the property to false throw an exception?
The reason for this is because the setter for UseDefaultCredentials
sets the Credentials
property to null if you set it to false, or it sets it to the CredentialCache.DefaultNetworkCredentials
property if set to true. The DefaultNetworkCredentials
property is defined by MSDN as:
The credentials returned by DefaultNetworkCredentials represents the authentication credentials for the current security context in which the application is running. For a client-side application, these are usually the Windows credentials (user name, password, and domain) of the user running the application. For ASP.NET applications, the default network credentials are the user credentials of the logged-in user, or the user being impersonated.
When you set UseDefaultCredentials
to true, it's using your IIS user, and I'm assuming that your IIS user does not have the same authentication credentials as your account for whatever SMTP server you're using. Setting UseDefaultCredentials
to false null's out the credentials that are set. So either way you're getting that error.
CredentialCache.DefaultNetworkCredentials is empty and so is Thread.CurrentPrincipal.Identity.Name
using System; using System.Net; using System.Security.Principal; namespace ConsoleApp1 { class Program { static void Main(string[] args) { var credential = CredentialCache.DefaultNetworkCredentials; Console.WriteLine($"credential.Domain={credential.Domain}"); Console.WriteLine($"credential.UserName={credential.UserName}"); Console.WriteLine($"credential.Password={credential.Password}"); Console.WriteLine($"credential.SecurePassword={credential.SecurePassword.Length}"); Console.WriteLine($"WindowsIdentity.GetCurrent().Name={WindowsIdentity.GetCurrent().Name}"); Console.WriteLine($"Environment.UserName={Environment.UserName}"); Console.ReadLine(); } } }
一个带了域名,另外一个不带域名
SmtpClient Class
Important
We don't recommend that you use the SmtpClient
class for new development because SmtpClient
doesn't support many modern protocols. Use MailKit or other libraries instead. For more information, see SmtpClient shouldn't be used on GitHub.
The SmtpClient
class is obsolete in Xamarin. However:
- It is included in the .NET Standard 2.0 and later versions and therefore must be part of any .NET implementation that supports those versions.
- It is present and can be used in .NET Framework 4 through .NET Framework 4.8.
- It is usable in .NET Core, but its use isn't recommended.
Microsoft has officially marked a .NET class as being replaced by an open source library.
The documentation for SmtpClient
now reads,
Obsolete("SmtpClient and its network of types are poorly designed, we strongly recommend you use https://github.com/jstedfast/MailKit and https://github.com/jstedfast/MimeKit instead")
The main problem with SmtpClient is that it has a confusing connection lifecycle.
Connecting to a SMTP server can be time-consuming, especially if authentication is enabled, so each SmtpClient
object has an internal connection pool.
This is a rather strange design. Consider for a moment a typical database connection. When you call Dispose on a SqlClient
, the underlying connection is returned to the pool. When you create a new SqlClient
, the pool is checked for an active connection with the same connection string.
With SmtpClient
, calling Dispose
closes all of the connections and drains that object’s connection pool. This means you can’t use it with the typical using
block pattern.
A well-known approach of the shared instance like HttpClient
cannot be used in SmtpClient
.
Well, no. , Unlike HttpClient
, the Send
/SendAsync
methods are not thread thread-safe. So unless you want to introduce your own synchronization scheme, you can’t use it that way either. In fact, the documentation for SmtpClient
warns,
By contrast, the SMTP client in MailKit represents a simple connection to a single server. By eliminating the complexity caused by internal connection pools, it actually makes it easier to create an application-specific pool for MailKit’s connection object.
作者:Chuck Lu GitHub |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2018-03-30 BootStrap自带的图标